结构体和示例说明

p7.pem文本内容示例:

-----BEGIN PKCS7-----
MIIFDAYKKoEcz1UGAQQCBKCCBPwwggT4AgEBMYIBJzCCASMCAQAwgZAwgYYxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJIQjELMAkGA1UEBwwCV0gxEDAOBgNVBAoMB0luZm9TZWMxEjAQBgNVBAsMCVNTTC1Hcm91cDESMBAGA1UEAwwJRUNDRGVtb0NBMSMwIQYJKoZIhvcNAQkBFhRlbWFpbEBpbmZvc2VjLmNvbS5jbgIFFwEDF1UwDQYJKoEcz1UBgi0DBQAEfDB5AiEA6joyvPmCXrzkFM/Hj1kf6JcNWicUGT5cvXqWHmcyHmsCIEhzc7TIF8oIaF0mcLJ/DfnkX4v5GTv8RFEBsKhqC8+2BCDCpremE5cKPdXMXamd5l7ZP2yP+wp7VYx3vnSVl2SL5gQQrfwe5v5cG39MH46CzWkVqwAxDjAMBggqgRzPVQGDEQUAMDwGCiqBHM9VBgEEAgEwHAYIKoEcz1UBaAIEEMWQtu6KZJ0E/BXdo8U107GAENtdQcRvikZ3ifkcxPUWVnigggJ0MIICcDCCAhagAwIBAgIFFwEDF1UwCgYIKoEcz1UBg3UwgYYxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJIQjELMAkGA1UEBwwCV0gxEDAOBgNVBAoMB0luZm9TZWMxEjAQBgNVBAsMCVNTTC1Hcm91cDESMBAGA1UEAwwJRUNDRGVtb0NBMSMwIQYJKoZIhvcNAQkBFhRlbWFpbEBpbmZvc2VjLmNvbS5jbjAeFw0xNzAxMDMxMDA4MTBaFw0yNjExMTIxMDA4MTBaMHsxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJIQjEQMA4GA1UECgwHSW5mb1NlYzESMBAGA1UECwwJU1NMLUdyb3VwMRQwEgYDVQQDDAtFQ0NTaWduVXNlcjEjMCEGCSqGSIb3DQEJARYUZW1haWxAaW5mb3NlYy5jb20uY24wWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAQ4PGbJsJpjqL6A6/Shmjk9bcOgU5uEDxjeQs0UWkPENY0KehNughYIR8QeUhWtLg6hNcr+0qcUldn01A+2vGyzo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUyabmGcopCxQxR8KdoajvrhEVemUwHwYDVR0jBBgwFoAUwnvRpdmD6ha5TMmcRWkxZxk16QMwCgYIKoEcz1UBg3UDSAAwRQIgDtU1XG2CYcoaJBe+34dfVseFiHLPIBYUfVyges37TVcCIQC8C91sIg3xiyXcwtxNmmWHKIzMTxTBZv+KilRgZehPjDGCAQAwgf0CAQEwgZAwgYYxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJIQjELMAkGA1UEBwwCV0gxEDAOBgNVBAoMB0luZm9TZWMxEjAQBgNVBAsMCVNTTC1Hcm91cDESMBAGA1UEAwwJRUNDRGVtb0NBMSMwIQYJKoZIhvcNAQkBFhRlbWFpbEBpbmZvc2VjLmNvbS5jbgIFFwEDF1UwDAYIKoEcz1UBgxEFADANBgkqgRzPVQGCLQEFAARIMEYCIQDrYTDMByQhxsCctfaDrxtLYEy/MtOkb7jvoYLrLQ6q3gIhAM4tu5A2fSJ9fjzQuky0bN0M2xKkcEv3Bo1r919LplNV
-----END PKCS7-----

P7结构体:

typedef struct pkcs7_st{/* The following is non NULL if it contains ASN1 encoding of* this structure */unsigned char *asn1;long length;#define PKCS7_S_HEADER    0
#define PKCS7_S_BODY    1
#define PKCS7_S_TAIL    2int state; /* used during processing */int detached;ASN1_OBJECT *type;/* content as defined by the type *//* all encryption/message digests are applied to the 'contents',* leaving out the 'type' field. */union  {char *ptr;/* NID_pkcs7_data */ASN1_OCTET_STRING *data;/* NID_pkcs7_signed */PKCS7_SIGNED *sign;/* NID_pkcs7_enveloped */PKCS7_ENVELOPE *enveloped;/* NID_pkcs7_signedAndEnveloped */PKCS7_SIGN_ENVELOPE *signed_and_enveloped;/* NID_pkcs7_digest */PKCS7_DIGEST *digest;/* NID_pkcs7_encrypted */PKCS7_ENCRYPT *encrypted;/* Anything else */ASN1_TYPE *other;} d;} PKCS7;

带签名的数字信封结构体:

typedef struct pkcs7_signedandenveloped_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; //签名者信息PKCS7_ENC_CONTENT *enc_data;       //对称密钥加密过后的密文STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;     //接收者信息,包含加密过后的对称密钥
} PKCS7_SIGN_ENVELOPE;

通过指针一级级获取指定内容进行解密

部分代码示例:

void parse_pkcs7() {//从文本中读取P7结构体BIO *cert_bio = BIO_new_file("./p7.pem", "r");PKCS7 *p7 = NULL;p7=PEM_read_bio_PKCS7(cert_bio,NULL,NULL,NULL);if(p7 == NULL) {fprintf(stderr, "p7 = null\n");return;}//打印P7结构BIO *m_out = BIO_new_fp(stderr, BIO_NOCLOSE);PKCS7_print_ctx(m_out, p7, 0, NULL);//获取P7结构中信息STACK_OF(PKCS7_RECIP_INFO) *rsk = p7->d.signed_and_enveloped->recipientinfo;PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rsk, 0);//读取加密私钥BIO *key_bio = BIO_new_file("./key.pem", "r");EVP_PKEY *pkey = PEM_read_bio_PrivateKey(key_bio, NULL, NULL, "11111111");if(pkey == NULL) {fprintf(stderr, "PEM_read_bio_PrivateKey fail\n");ERR_print_errors_fp(stderr);}unsigned char *pek = NULL;int peklen = 1024;fprintf(stderr, "22222222222222\n");//解密P7结构中的接收者信息if(pkcs7_decrypt_rinfo(&pek, &peklen, ri, pkey) == 0) {fprintf(stderr, "pkcs7_decrypt_rinfo fail\n");return;}fprintf(stderr, "111111111111111111\n");//打印sm4对称密钥PRINT_HEX("pek", pek, peklen);//sm4解密获取原文sms4_key_t dec;sms4_set_decrypt_key(&dec, pek);unsigned char out[2048] = {0};unsigned char prikey[2048] = {0};int outlen = 0; memset(out, 0, 1024);int tmplen = 0;//获取密文ASN1_OCTET_STRING *data_body = NULL;data_body = p7->d.signed_and_enveloped->enc_data->enc_data;sms4_ecb_encrypt(data_body->data, out, &dec, 0);for (tmplen=SMS4_BLOCK_SIZE; tmplen<data_body->length; tmplen+=SMS4_BLOCK_SIZE)sms4_ecb_encrypt(data_body->data+tmplen, out+tmplen, &dec, SMS4_DECRYPT);//打印原文   PRINT_HEX("un-encpri",out,tmplen);return;
}

该释放内存的记得释放内存,此处未处理。

通过P7函数接口进行解密(包含验签)

部分代码示例:

 //读取P7BIO *m_out = BIO_new_fp(stdout, BIO_NOCLOSE);PKCS7_print_ctx(m_out, v_p7, 0, NULL);//获取P7中的证书if(OBJ_obj2nid((v_p7)->type) == NID_pkcs7_signedAndEnveloped){STACK_OF(X509) *cert = v_p7->d.signed_and_enveloped->cert;X509 *x509_sign = X509_dup(sk_X509_value(cert, 0));}//打印证书X509_print_fp(stdout, x509_sign);//获取加密证书BIO *bio = BIO_new_file(cert_file, "r");X509 *x509_enc = PEM_read_bio_X509(bio, NULL, 0, NULL);//获取私钥BIO *key_bio = BIO_new_file(key_file, "r");EVP_PKEY *pkey = PEM_read_bio_PrivateKey(key_bio, NULL, NULL, "11111111");//解析出原始数据//EVP_rc4 无法正常解密,需要额外处理v_p7bio = PKCS7_dataDecode(v_p7, pkey, NULL, x509_enc);if (v_p7bio == NULL) {printf("v_p7bio is null.\n");return;}//获取原文user_data->len = BIO_ctrl_pending(v_p7bio);user_data->data = (unsigned char *)malloc(user_data->len);user_data->len = BIO_read(v_p7bio, user_data->data, user_data->len);if ((int)user_data->len <= 0) {if (user_data->data) {free(user_data->data);user_data->data = NULL;}}//这一步很重要,不然BIO位置已经发生变化无法正确读取到int rv = 0; rv = BIO_reset(v_p7bio);//获取签名相关信息STACK_OF(PKCS7_SIGNER_INFO) *signifos;signifos=PKCS7_get_signer_info(v_p7);if (signifos == NULL) {        printf("signifos is null.\n");return;} else {ERR_clear_error();for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(signifos); i++) {si = sk_PKCS7_SIGNER_INFO_value(signifos, i);int j = 0;//验签j = PKCS7_signatureVerify(v_p7bio, v_p7, si, x509_sign);if (j <= 0) {printf("PKCS7 signatures error.\n");return;}}}

该释放内存的记得释放内存,此处未处理。

PKCS7带签名的数字信封相关推荐

  1. java p7 数字签名,p7结构的数字信封 | 学步园

    PKCS7的数字信封格式分为两种:带签名的数字信封和不带签名的数字信封.由于这个数字信封的生成过程比较复杂,所以这两种格式比较容易记混,导致都搞不清楚一个数字信封里面到底是存储的什么内容了.下面我就详 ...

  2. 数字信封的介绍2.0:定义,优点,原理

    1.什么是数字信封? 数字信封是将对称密钥通过非对称加密(即:有公钥和私钥两个)的结果分发对称密钥的方法. PKCS#7中数字信封包含被加密的内容和被加密的用于加密该内容的密钥. 通常使用接收方的公钥 ...

  3. PKCS1签名、PKCS7签名、PKCS数字信封

    1.1 PKCS#1签名 被签名的数据为字节数组.对给出的被签名原数据进行Hash运算,Hash结果按PKCS#1标准进行填充: B = 00 01 ff ff - ff 00 30 - H[00], ...

  4. 签名证书、数字签名和数字信封

    签名证书 作为文件形式存在的证书一般有这几种格式:   1.带有私钥的证书    由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥 ...

  5. 密码学数字信封的介绍

    对称密码和非对称密码 对称密码:加解密运算非常快,适合处理大批量数据,但其密码的分发与管理比较复杂 非对称密码:公钥和私钥分离,非常适合密钥的分发和管理 数字信封的定义 如果将对称密码算法和非对称密码 ...

  6. 数字签名与数字信封流程

    数字签名 数字签名(Digital Signature)(又称公钥数字签名.电子签章)是一种类似写在纸上的普通的物理签名,背后的思想是模仿传统手写签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信 ...

  7. PKCS7数字信封简述

    1.数字信封的概念 数字信封,英文是Digital Envelope,望文生义,就可以知道将需要传递的数据,通过加密的方式包裹起来. 数字信封的准确定义,在<PKCS #7: Cryptogra ...

  8. C#.NET 国密数字信封 民生银行

    民生银行的库DLL只有C版本和JAVA版本.按着JAVA版本做的C# 实现. 重点内容. 1.数字信封就是 CmsEnvelopedData Der编码后转BASE64 2.重点类:ContentIn ...

  9. sm2格式数字信封加解密详解

    sm2格式数字信封 0.参考链接 密码行业标准化技术委员会http://www.gmbz.org.cn/main/bzlb.html SM2密码算法使用规范http://www.gmbz.org.cn ...

最新文章

  1. Java程序的运行原理 用记事本编写Java代码
  2. 通过Clocking Wizard定制和生成一个IP核(MMCM)(Virtex7)(ISE版)
  3. operator new/delete,operator-> / *【C++运算符重载】
  4. VirtualBox安装及Linux基本操作(操作系统实验一)
  5. C语言笔试两题,有坑
  6. 第六章 相同的功能,不同的代码
  7. 【华为云技术分享】华为专家亲述:如何转型搞 AI?
  8. IBM 、M$ 、Google Apple
  9. 基于Django进行简单的微信开发
  10. MySQL(三) —— 约束以及修改数据表
  11. 残差网络 ResNet 为什么能训练出1000层的模型 动手学深度学习v2
  12. vim编辑器使用教程
  13. 国际象棋游戏测试软件,Fritz国际象棋测试_CPUCPU评测-中关村在线
  14. Java制作银行管理系统_java代码实现银行管理系统
  15. linux文件系统程序设计实验报告,浙江大学Linux程序设计实验报告
  16. ORACEL R12 总账和子账的关系
  17. Chatgpt 指令收集
  18. 最全的Office 2003图标集合
  19. L0,L1,L2正则化浅析
  20. Sourcetree安装详细(最新版本)

热门文章

  1. 穿刺检查、代理http proxy、https proxy、Socks,代理本质上就是一个中介
  2. 安卓手机为何败退?因安卓芯片都是组装芯片,苹果才是真自主研发
  3. 《数字短片创作(修订版)》——利用隐喻和符号讲故事
  4. 兄弟生日祝福语霸气简短搞笑
  5. win10系统克隆到新硬盘,如何克隆系统到新硬盘
  6. 房地产行业如何做投资分析?这篇文章告诉你
  7. Qt - Lambda表达式
  8. 华硕bios开启虚拟化linux,华硕主板进入bios后怎么开启VT虚拟化技术选项?
  9. 微信发照片怎么在服务器上删除,为什么微信里面有的照片,相册里面没有,怎么删除...-卓优商学问答...
  10. 资深工程师 VSCode C/C++ 必备开发插件