PKCS7带签名的数字信封
结构体和示例说明
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带签名的数字信封相关推荐
- java p7 数字签名,p7结构的数字信封 | 学步园
PKCS7的数字信封格式分为两种:带签名的数字信封和不带签名的数字信封.由于这个数字信封的生成过程比较复杂,所以这两种格式比较容易记混,导致都搞不清楚一个数字信封里面到底是存储的什么内容了.下面我就详 ...
- 数字信封的介绍2.0:定义,优点,原理
1.什么是数字信封? 数字信封是将对称密钥通过非对称加密(即:有公钥和私钥两个)的结果分发对称密钥的方法. PKCS#7中数字信封包含被加密的内容和被加密的用于加密该内容的密钥. 通常使用接收方的公钥 ...
- PKCS1签名、PKCS7签名、PKCS数字信封
1.1 PKCS#1签名 被签名的数据为字节数组.对给出的被签名原数据进行Hash运算,Hash结果按PKCS#1标准进行填充: B = 00 01 ff ff - ff 00 30 - H[00], ...
- 签名证书、数字签名和数字信封
签名证书 作为文件形式存在的证书一般有这几种格式: 1.带有私钥的证书 由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥 ...
- 密码学数字信封的介绍
对称密码和非对称密码 对称密码:加解密运算非常快,适合处理大批量数据,但其密码的分发与管理比较复杂 非对称密码:公钥和私钥分离,非常适合密钥的分发和管理 数字信封的定义 如果将对称密码算法和非对称密码 ...
- 数字签名与数字信封流程
数字签名 数字签名(Digital Signature)(又称公钥数字签名.电子签章)是一种类似写在纸上的普通的物理签名,背后的思想是模仿传统手写签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信 ...
- PKCS7数字信封简述
1.数字信封的概念 数字信封,英文是Digital Envelope,望文生义,就可以知道将需要传递的数据,通过加密的方式包裹起来. 数字信封的准确定义,在<PKCS #7: Cryptogra ...
- C#.NET 国密数字信封 民生银行
民生银行的库DLL只有C版本和JAVA版本.按着JAVA版本做的C# 实现. 重点内容. 1.数字信封就是 CmsEnvelopedData Der编码后转BASE64 2.重点类:ContentIn ...
- sm2格式数字信封加解密详解
sm2格式数字信封 0.参考链接 密码行业标准化技术委员会http://www.gmbz.org.cn/main/bzlb.html SM2密码算法使用规范http://www.gmbz.org.cn ...
最新文章
- Java程序的运行原理 用记事本编写Java代码
- 通过Clocking Wizard定制和生成一个IP核(MMCM)(Virtex7)(ISE版)
- operator new/delete,operator-> / *【C++运算符重载】
- VirtualBox安装及Linux基本操作(操作系统实验一)
- C语言笔试两题,有坑
- 第六章 相同的功能,不同的代码
- 【华为云技术分享】华为专家亲述:如何转型搞 AI?
- IBM 、M$ 、Google Apple
- 基于Django进行简单的微信开发
- MySQL(三) —— 约束以及修改数据表
- 残差网络 ResNet 为什么能训练出1000层的模型 动手学深度学习v2
- vim编辑器使用教程
- 国际象棋游戏测试软件,Fritz国际象棋测试_CPUCPU评测-中关村在线
- Java制作银行管理系统_java代码实现银行管理系统
- linux文件系统程序设计实验报告,浙江大学Linux程序设计实验报告
- ORACEL R12 总账和子账的关系
- Chatgpt 指令收集
- 最全的Office 2003图标集合
- L0,L1,L2正则化浅析
- Sourcetree安装详细(最新版本)
热门文章
- 穿刺检查、代理http proxy、https proxy、Socks,代理本质上就是一个中介
- 安卓手机为何败退?因安卓芯片都是组装芯片,苹果才是真自主研发
- 《数字短片创作(修订版)》——利用隐喻和符号讲故事
- 兄弟生日祝福语霸气简短搞笑
- win10系统克隆到新硬盘,如何克隆系统到新硬盘
- 房地产行业如何做投资分析?这篇文章告诉你
- Qt - Lambda表达式
- 华硕bios开启虚拟化linux,华硕主板进入bios后怎么开启VT虚拟化技术选项?
- 微信发照片怎么在服务器上删除,为什么微信里面有的照片,相册里面没有,怎么删除...-卓优商学问答...
- 资深工程师 VSCode C/C++ 必备开发插件