PKCS7 簽名


Openssl之Pkcs7之3 Signed-Data內容類型的編碼解碼

PKCS7_SIGNED.sign在openssl中的定義如下:

typedef struct pkcs7_signed_st

{

ASN1_INTEGER *version; /* version 1 */

STACK_OF(X509_ALGOR) *md_algs; /* md used */

STACK_OF(X509) *cert; /* [ 0 ] */

STACK_OF(X509_CRL) *crl; /* [ 1 ] */

STACK_OF(PKCS7_SIGNER_INFO) *signer_info;

struct pkcs7_st *contents;

} PKCS7_SIGNED;

signed內容類型由任意類型的內容和數字簽名組成。任何類型的內容能夠同時被任意數量的簽名者簽名。

簽名數據的產生過程有如下幾步

1. 對於每一個簽名者,他用消息摘要算法計算出摘要值 。

2. 對於每一個簽名者,消息摘要和相關的信息用自己的私鑰加密。

3. 對於每一個簽名者,把加密的消息摘要和其他的簽名者特定信息放入signer_info值中。每個 簽名者的證書、crl等也在這一步被收集進來。

4. 把所有簽名者的信息摘要算法、他們的signer_info值和內容一起放進sign值中。

調用openssl的代碼如下:

PKCS7* p7 = PKCS7_new();

PKCS7_set_type(p7, NID_pkcs7_signed);//設置類型為NID_pkcs7_signed

PKCS7_content_new(p7, NID_pkcs7_data);

PKCS7_set_detached(p7, 0);

//添加簽名者信息,

//x509:簽名證書,pkey:簽名者私鑰。EVP_sha1()簽名者摘要算法。

PKCS7_SIGNER_INFO* info = PKCS7_add_signature(p7, x509, pkey, EVP_sha1());

//添加簽名者證書

PKCS7_add_certificate(p7, x509);

//添加簽名者的CA證書鏈

for (int i=0; i<sk_X509_num(ca); i++)

{

     PKCS7_add_certificate(p7, sk_X509_value(ca, i));

}

BIO* p7bio = PKCS7_dataInit(p7, NULL);

BIO_write(p7bio, "How are you!", strlen("How are you!"));//加入原始數據,

PKCS7_dataFinal(p7, p7bio); //處理數據。

//轉換為der編碼輸出

i2d_PKCS7(p7,&dertmp);

PKCS7_free(p7);

BIO_free(p7bio);

解析P7簽名的代碼:

//der編碼轉換為PKCS7結構體

PKCS7 * p7 =d2i_PKCS7(NULL,dertmp,derLen)

//解析出原始數據

BIO *p7bio= PKCS7_dataDecode(p7,NULL,NULL,NULL);

//從BIO中讀取原始數據,將得到"How are you!"

srcLen = BIO_read(p7bio,src,1024);

//獲得簽名者信息stack

STACK_OF(PKCS7_SIGNER_INFO) *sk = PKCS7_get_signer_info(p7);

//獲得簽名者個數(本例只有1個)

int signCount = sk_PKCS7_SIGNER_INFO_num(sk );

for(int i=0;i

{

//獲得簽名者信息

PKCS7_SIGNER_INFO *signInfo = sk_PKCS7_SIGNER_INFO_value(sk,i);

//獲得簽名者證書

X509 *cert= PKCS7_cert_from_signer_info(p7,signInfo);

//驗證簽名

if(PKCS7_signatureVerify(p7bio,p7,signInfo,cert) != 1)

{

printf("signatureVerify Err\n");

}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM