openssl 加解密學習筆記

來源:互聯網
上載者:User

標籤:rsa演算法 openssl cer公開金鑰


    首先最近接到一個項目,這個項目中需要用到RSA的加密解密,因為之前沒有接觸過,在網上找了些資料,然後自己測試後發現其實使用openssl來進行加解密挺簡單的,但是網上百度出來的很多又是一樣的,有時候協助不是很大,所以才想要寫下來自己在搞整個加密過程遇到的一些問題,方便自己以後回頭查看,也可能會幫到遇到同樣的童鞋。

    廢話不多說,我接到的這個項目呢,有幾個地方是需要用到RSA的加解密。1、使用.pfx格式的私密金鑰簽名。2、使用.cer的公開金鑰檔案進行加密操作。3、使用給定的指數與模進行公開金鑰加密。下面有些自己從網上整理的代碼,歡迎批評指正。

1、使用.pfx格式的私密金鑰進行簽名(部分代碼來源網上):

/**   <pre name="code" class="cpp"><pre name="code" class="cpp">*    SrcData:需要加密的字串


 
*     PriPath:私密金鑰檔案(.pfx格式)*   PassWd:私密金鑰檔案密碼*   SignData:結果 */int SignDataByPri(char *SrcData,char *PriPath,char *PassWd,char *SignData){    int err;    unsigned int   SigLen;    unsigned char SigBuf[128];    EVP_MD_CTX MdCtx;    EVP_PKEY *Pkey = NULL;    FILE *Fp = NULL;    X509 *X509 = NULL;    PKCS12 *P12 = NULL;    STACK_OF(X509) *Ca = NULL;    if(SrcData == NULL || PriPath == NULL){        return false;    }    SSLeay_add_all_algorithms();    ERR_load_crypto_strings();    if (!(Fp = fopen(PriPath, "rb"))) {        printf("讀取密鑰檔案失敗\n");        return false;    }    P12 = d2i_PKCS12_fp(Fp, NULL);    fclose (Fp);    if (!P12) {        printf("讀取密鑰檔案失敗\n");        return false;    }    if (!PKCS12_parse(P12, PassWd, &Pkey, &X509, &Ca)) {        printf("解包密鑰失敗\n");        PKCS12_free(P12);        return false;    }    PKCS12_free(P12);    if (Pkey == NULL) {        printf("解包密鑰失敗\n");        return false;    }    /*簽名資料*/      EVP_SignInit   (&MdCtx, EVP_sha1());  //簽名演算法選擇sha1    EVP_SignUpdate (&MdCtx, SrcData, strlen(SrcData));    SigLen = 128;    memset(SigBuf,0x00,sizeof(SigBuf));    err = EVP_SignFinal (&MdCtx, SigBuf, &SigLen, Pkey);    if (err != 1) {        printf("簽名失敗\n");        /*釋放相關變數*/        if (Pkey) {            EVP_PKEY_free (Pkey);        }        if (X509) {            X509_free(X509);        }        return false;    }    memcpy(SignData, SigBuf, SigLen);    /*釋放相關變數*/    if (Pkey) {        EVP_PKEY_free (Pkey);    }    if (X509) {        X509_free(X509);    }    return true;}

 

2、使用.cer的公開金鑰檔案對字串進行加密操作:

/**    src:需要加密的源字串*    len:src的長度*    path_key:公開金鑰檔案的路徑(.cer格式)*/int RSAencrypt(char *str,int len,char *path_key,char *Enc){    char *p_en;    RSA *p_rsa;    FILE *file;    int flen,rsa_len;    PKCS12*     p12 = NULL;      X509 *     x509 = NULL;      STACK_OF(X509) *ca = NULL;      EVP_PKEY *     pkey = NULL;      if((file=fopen(path_key,"r"))==NULL){        perror("open key file error");        return 0;        }       BIO* b;    b=BIO_new_file(path_key,"r");    x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);    if (x509 == NULL) {        printf("讀密鑰檔案 \n");        ERR_print_errors_fp (stderr);        return 0;    }     printf("讀密鑰檔案 [%d]\n",__LINE__);    pkey=X509_get_pubkey(x509);    //將EVP_KEY轉成RSA KEY (這步很重要)    p_rsa =  EVP_PKEY_get1_RSA(pkey);    rsa_len=RSA_size(p_rsa);    p_en=(unsigned char *)malloc(rsa_len+1);    memset(p_en,0,rsa_len+1);    //網山很多例子這個函數調用時第一個參數使用的是密鑰的長度是因為他們加密方式使用RSA_NO_PADDING,如使用RSA_PKCS1_PADDING,len需要填源字串長度        if(RSA_public_encrypt(len,str,p_en,p_rsa,RSA_PKCS1_PADDING)<0){        printf("加密失敗\n");        return 0;    }    memcpy(Enc,p_en,rsa_len);    fclose(file);    free(p_en);    return rsa_len;}

3、使用給定的指數與模進行公開金鑰加密

/**   type:一般分為10進位和16進位*   Bnn:模,進位數與type對應*   Bne:通常分為兩種RSA_F4和RSA_3(在rsa.h定義)*   in:需要加密的來源資料* out:加密後的密文*/int RSAEncryptByModule(int type,char *Bnn,int Bne,unsigned char *in,unsigned char *out ) {    int ret, flen;    BIGNUM *bnn, *bne, *bnd;    unsigned char *out_buf;    bnn = BN_new();    bne = BN_new();    bnd = BN_new();    switch(type){        case 10:            BN_dec2bn(&bnn, Bnn);            BN_set_word(bne, Bne);            break;        case 16:            BN_hex2bn(&bnn, Bnn);            BN_set_word(bne, Bne);            break;        default:            printf("err type\n");            return -1;    }        RSA *r = RSA_new();    r->n = bnn;    r->e = bne;    r->d = bnd;    flen = RSA_size(r);    out_buf = ( unsigned char *)malloc(flen);    memset(out_buf, 0, flen);    <pre name="code" class="cpp">    //網山很多例子這個函數調用時第一個參數使用的是密鑰的長度是因為他們加密方式使用RSA_NO_PADDING,如使用RSA_PKCS1_PADDING,len需要填源字串長度     ret = RSA_public_encrypt(strlen(in),in,out_buf,r,RSA_PKCS1_PADDING);    if (ret < 0)    {        printf("Encrypt failed!\n");        return ret;    }    memcpy(out,out_buf,ret);    free(out_buf);    RSA_free(r);    return ret;} 
 
 


還有一些比如sha1做簽名、base64轉碼等操作就不一一贅述了,網上也很多代碼和解釋。

openssl 加解密學習筆記

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.