PKCS7签名代码

#include <stdlib.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/pkcs7.h>
#include <openssl/objects.h>
#include <openssl/x509.h>

#define DATA_LEN 1024

int PKCS7_sign_Me(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, BIO *data, int flags, char*Base64Sign);
int PKCS7_sign_Me(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, BIO *data, int flags, char*Base64Sign)
{
	PKCS7 *P7_sign;
    int i;

    if ((P7_sign = PKCS7_new()) == NULL)
    {
        //ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
        return -1;
    }

    if (!PKCS7_set_type(P7_sign, NID_pkcs7_signed))
        goto err;

    if (!PKCS7_content_new(P7_sign, NID_pkcs7_data))
        goto err;

    if (private_key && !PKCS7_sign_add_signer(P7_sign, signcert, private_key, NULL, flags))
    {
        printf("ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNER_ERROR");
        goto err;
    }

    if (!(flags & PKCS7_NOCERTS))
    {
        for (i = 0; i < sk_X509_num(certs); i++)
        {
            if (!PKCS7_add_certificate(P7_sign, sk_X509_value(certs, i)))
                goto err;
        }
    }

    if (flags & PKCS7_DETACHED)
        PKCS7_set_detached(P7_sign, 1);

    if (PKCS7_final(P7_sign, data, flags))
	{
		int li_len = 0;
		char *p_str = NULL;

    	//ASNI转DER编码	
    	if (Asni2Der(P7_sign, &li_len, &p_str) == -1)
    	{
        	return -1;
    	}

    	//Base64编码操作 字符可见
    	unsigned char *per = NULL;
    	EVP_EncodeBlock(Base64Sign, (unsigned char*)*per, li_len);
    	printf("签名完成,Base64 Data =[%s] len = [%d]\n",Base64Sign, li_len);

	}

err:
	PKCS7_free(P7_sign);
	return -1;

}

//签名校验
int PKCS7_SignVerify_Me(char *Base64Sign);
int PKCS7_SignVerify_Me(char *Base64Sign)
{
	//Base64解码操作
    unsigned char lc_Sign_Der[DATA_LEN];
	int li_signB64_len=strlen(Base64Sign);
	int li_len=EVP_DecodeBlock (lc_Sign_Der, Base64Sign, li_signB64_len);
	printf("befor len=%d\n",li_signB64_len);
	while(Base64Sign[--li_signB64_len]== '=')
	li_len--;

	printf("after len=%d\n",li_len);

    //Der2Asni
    PKCS7*p7_Decode_Sign = d2i_PKCS7(NULL, &lc_Sign_Der, li_len);
    if(!p7_Decode_Sign)
    {
        printf("build p7 sign object failed \n");
        return -1;
    }

	//验签
    int li_code = PKCS7_signatureVerify_Me(p7_Decode_Sign);
    if(li_code == -1)
    {
        printf("signatureVerify failed \n");
        return -1;
    }

}

//签名校验
int PKCS7_signatureVerify_Me(PKCS7 *p7_res_sign);
int PKCS7_signatureVerify_Me(PKCS7 *p7_res_sign)
{
	BIO * p7bio_AA = PKCS7_dataDecode(p7_res_sign, NULL,NULL,NULL);
	int len=BIO_ctrl_pending(p7bio_AA);
	if(len <= 0)
	{
		printf("get data length failed\n");
		return -1;
	}
	else
	{
		char decode_data_2[10240]={0};
		int write_len=BIO_read(p7bio_AA, decode_data_2,len);
		printf( "buffer data is %s /n",decode_data_2);
		//获得签名者信息stack
		STACK_OF(PKCS7_SIGNER_INFO) *sk = PKCS7_get_signer_info(p7_res_sign);
		int signCount=sk_PKCS7_SIGNER_INFO_num(sk);
		int li_num=0;
		for(li_num; li_num < sk_PKCS7_SIGNER_INFO_num(sk); li_num++)
		{
			//获得签名者信息
			PKCS7_SIGNER_INFO *signInfo = sk_PKCS7_SIGNER_INFO_value(sk,li_num);
			
			//获得签名者证书
			X509 *cert= PKCS7_cert_from_signer_info(p7_res_sign,signInfo);
			//验证签名
			if(PKCS7_signatureVerify(p7bio_AA, p7_res_sign, signInfo, cert) != 1)
			{
				printf("usignatureVerify Erri/n");
				return -1;
			}
		}
	}
	
	BIO_free(p7bio_AA);
	return 1;
}

//ASNI转DER编码
int Asni2Der(PKCS7* p7, int *li_len, unsigned char**p_str);
int Asni2Der(PKCS7* p7, int *li_len, unsigned char**p_str)
{   
    unsigned char*der = NULL;
    unsigned char*derTmp;
    int len = i2d_PKCS7(p7,NULL);
	der=(unsigned char*)malloc(len);
    if(der == NULL) return -1;
	printf("der code length=%d\n",len);
	memset(der,0,len);
	derTmp=der;
	i2d_PKCS7(p7,(unsigned char **)&derTmp);
    *p_str = der;
    *li_len = len;
    return 0;
}

//测试加签延签流程
int Sign_SignVerify(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, int flags);
int Sign_SignVerify(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, int flags)
{
    char src_data[DATA_LEN];
    memset(src_data, 0x00, DATA_LEN);
    memcpy(src_data, "this is a secret", 16);

	unsigned char Base64Sign[DATA_LEN * 2];
    memset(Base64Sign, 0x00, sizeof(Base64Sign));
    BIO*sign_data=BIO_new(BIO_s_mem());
    BIO_puts(sign_data, src_data);

    //加签
    if (PKCS7_sign_Me(signcert, private_key, certs, sign_data, flags, Base64Sign) == -1)
	{
		return -1;
	}

	if (PKCS7_SignVerify_Me(Base64Sign) == -1)
	{
		return -1;
	}

	return 0;
}

//
//测试签名+数字信封
//int Sign_Enveloped();


int main(int argc, char*argv[])
{
	if(argc < 2)
	{
		printf("low argument\n");
		return -1;
	}
	
    int li_chose = argv[0];

    //读取证书和私钥
    char certfile[256];
	memset(certfile,0x00,sizeof(certfile));
	sprintf(certfile,"/home/wdy/CC/test.pem");

    BIO *infile, *p7bio;
	STACK_OF(X509) *certs = NULL;
	X509 *signcert=NULL;
	const EVP_CIPHER *cipher = NULL;
	if(!(infile=BIO_new_file(certfile,"r")))
		printf("BIO_new_file-ERROR/n");
	if(!(signcert=PEM_read_bio_X509(infile,NULL,NULL,NULL)))
		printf("PEM_read_bio_X509-ERROR/n");
	if(!certs) certs=sk_X509_new_null();
	sk_X509_push(certs,signcert);
	BIO_free(infile);

    EVP_PKEY* private_key = NULL;
    FILE* fp = fopen(certfile, "r");
	if (fp == NULL) 
		return -1;
    else
    {
        private_key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
	    fclose (fp);
    }

	int li_code = 0;
	if(li_chose == 1)
	{
		li_code= Sign_SignVerify(signcert, private_key, certs, PKCS7_NOSMIMECAP | PKCS7_BINARY);
	}
	else if(li_chose == 2)
	{

	}
	else if(li_chose == 3)
	{

	}
	else if(li_chose == 4)
	{

	}
	else
	{
		printf("ERROR!!!!!!\n");
	}
	
    
}
#if 0
int main()
{
	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();  
	
	char certfile[256];
	memset(certfile,0x00,sizeof(certfile));
	sprintf(certfile,"/home/wdy/CC/test.pem");
	char src_data[10240];
	memset(src_data, 0x00,sizeof(src_data));
	memcpy(src_data, "AAAAAAAAAAAAAAAAA", 17);
	char Base64Enevloped[10240]={0};
	BIO *infile, *p7bio;
	STACK_OF(X509) *certs = NULL;
	X509 *signcert=NULL;
	const EVP_CIPHER *cipher = NULL;
	if(!(infile=BIO_new_file(certfile,"r")))
		printf("BIO_new_file-ERROR/n");
	if(!(signcert=PEM_read_bio_X509(infile,NULL,NULL,NULL)))
		printf("PEM_read_bio_X509-ERROR/n");
	if(!certs) certs=sk_X509_new_null();
	sk_X509_push(certs,signcert);
	BIO_free(infile);
	if(!cipher) 
	{
	#ifndef OPENSSL_NO_DES
		cipher=EVP_des_ede3_cbc();
	#else
		printf("No cipher selected\n");
	#endif
	}
	
	BIO*p7_data_sign=BIO_new(BIO_s_mem());
	BIO_puts(p7_data_sign, src_data);
	
	FILE* fp = fopen (certfile, "r");
	if (fp == NULL) 
		return -1;
 
	/* Read private key */
	EVP_PKEY* private_key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
	fclose (fp);

	//构造签名
	PKCS7* P7_sign =  PKCS7_sign_Me(signcert, private_key, certs, p7_data_sign, PKCS7_DETACHED | PKCS7_NOSMIMECAP | 0x80);
	if(!P7_sign)
    {
		return -1;
	}		
	
	//ASN1转DER编码
	int len = i2d_PKCS7(P7_sign,NULL);
	unsigned char*der_sign = (unsigned char*)malloc(len);
	printf("sign der code length=%d\n",len);
	memset(der_sign,0,len);
	unsigned char*derTmp = der_sign;
	i2d_PKCS7(P7_sign,(unsigned char **)&derTmp);
	
	/*----测试打印sign----------------------begin-*/
	//转Base64编码(可见字符)
	char Base64encode[10240];
	memset(Base64encode, 0x00, sizeof(Base64encode));
	EVP_EncodeBlock(Base64encode, der_sign, len);
	printf("base lenth =%d, base der[%s]\n",strlen(Base64encode), Base64encode);
	/*----测试打印sign------------------------end-*/
	
	//DER签名数据作为信封的内容,再次加密
	
	BIO*p7_data_enc = BIO_new(BIO_s_mem());
	BIO_write(p7_data_enc, Base64encode, strlen(Base64encode));
	
	//释放空间
	BIO_free(p7_data_sign);
	PKCS7_free(P7_sign);
	free(der_sign);

	
	//数字信封加密
	PKCS7* p7_enveloped=PKCS7_encrypt(certs, p7_data_enc, cipher, 0X80);   
	if(!p7_enveloped)
	{
		printf("PKCS7 encrypt failed\n");
		return-1;
	}
	
	
	//ASN1转DER编码
	len = i2d_PKCS7(p7_enveloped,NULL);
	unsigned char*der=(unsigned char*)malloc(len);
	printf("der code length=%d\n",len);
	memset(der,0,len);
	derTmp=der;
	i2d_PKCS7(p7_enveloped,(unsigned char **)&derTmp);
	//转Base64编码(可见字符)
	EVP_EncodeBlock(Base64Enevloped,der,len);
	
	printf("base lenth =%d,base der[%s]\n",strlen(Base64Enevloped), Base64Enevloped);
	printf("PKCS7 签名+数字信封successed\n");
	
	//需要释放空间
	free(der);
	PKCS7_free(p7_enveloped);
	BIO_free(p7_data_enc);
	
	
	//从Base64编码的密文开始解密--------------------------------------------
	//base64编码转换->DER编码
	char enevlop_dec[10240]={0};
	int len_tmp=strlen(Base64Enevloped);
	len=EVP_DecodeBlock (enevlop_dec,Base64Enevloped,len_tmp);
	printf("befor len=%d\n",len);
	while(Base64Enevloped[--len_tmp]== '=')
	len--;
	
	printf("after len=%d\n",len);
	const unsigned char*p;
	p=enevlop_dec;
	
	//由DER编码的数据解析PKCS7信封
	PKCS7*p7=d2i_PKCS7(NULL,&p,len);
	if(!p7)
	{
		printf("Could not build PKCS7 struct\n");return -1;
	}

    FILE* fd=NULL;
    EVP_PKEY *rsa_privk=NULL;
	if((fd=fopen (certfile,"r")))
	{
	   rsa_privk = PEM_read_PrivateKey (fd,NULL,NULL,NULL);
	   if(!rsa_privk)
	   {
	   	   printf("Could not read private RSA key\n");
		   fclose(fd);
		   return-1;
	   }
	}
	
	//PKCS7_decrypt解密信封
	BIO*out_data=BIO_new(BIO_s_mem());
	
	if(PKCS7_decrypt(p7, rsa_privk, signcert, out_data, 0X80)>0)
		printf("prcs7_decrypt enevlod successed\n");
	
	int	len_l=BIO_ctrl_pending(out_data);
	char *out = NULL;
	out=(char *)OPENSSL_malloc(len_l);
	if(out == NULL)
	{
		printf("Could not malloc memory\n");
		return -1;
	}
	int len_ll=BIO_read(out_data,out,len_l);
	printf("解析签名BASE64数据:[%s], lenth = %d\n",out,len_l);
	
	//base64编码转换->DER编码
	char sign_dec[10240];
	len_tmp=strlen(out);
	len=EVP_DecodeBlock (sign_dec,out,len_tmp);
	printf("decode sign befor len=%d\n",len);
	while(out[--len_tmp]== '=')
	len--;
	
	printf("decode sign after len=%d\n",len);
	p=sign_dec;
	
	//从信封中解密出来签名数据,
	PKCS7*p7_res_sign=d2i_PKCS7(NULL, &sign_dec, len_ll);
	//解Base64再去验签
	
	//OPENSSL_free(out);
	//BIO_free(out_data);
	
	if(!p7_res_sign)
	{
		printf("Could not build PKCS7 sign struct\n");
		return -1;
	}
	int li_code = PKCS7_signatureVerify_Me(p7_res_sign);
	if(li_code == -1)
	{
		return -1;
	}
	return 1;
}
#endif





#include <stdlib.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/pkcs7.h>
#include <openssl/objects.h>
#include <openssl/x509.h>

#define DATA_LEN 1024

int PKCS7_sign_Me(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, BIO *data, int flags, char*Base64Sign);
int PKCS7_sign_Me(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, BIO *data, int flags, char*Base64Sign)
{
	PKCS7 *P7_sign;
    int i;

    if ((P7_sign = PKCS7_new()) == NULL)
    {
        //ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
        return -1;
    }

    if (!PKCS7_set_type(P7_sign, NID_pkcs7_signed))
        goto err;

    if (!PKCS7_content_new(P7_sign, NID_pkcs7_data))
        goto err;

    if (private_key && !PKCS7_sign_add_signer(P7_sign, signcert, private_key, NULL, flags))
    {
        printf("ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNER_ERROR");
        goto err;
    }

    if (!(flags & PKCS7_NOCERTS))
    {
        for (i = 0; i < sk_X509_num(certs); i++)
        {
            if (!PKCS7_add_certificate(P7_sign, sk_X509_value(certs, i)))
                goto err;
        }
    }

    if (flags & PKCS7_DETACHED)
        PKCS7_set_detached(P7_sign, 1);

    if (PKCS7_final(P7_sign, data, flags))
	{
		int li_len = 0;
		char *p_str = NULL;

    	//ASNI转DER编码	
    	if (Asni2Der(P7_sign, &li_len, &p_str) == -1)
    	{
        	return -1;
    	}

    	//Base64编码操作 字符可见
    	unsigned char *per = NULL;
    	EVP_EncodeBlock(Base64Sign, (unsigned char*)*per, li_len);
    	printf("签名完成,Base64 Data =[%s] len = [%d]\n",Base64Sign, li_len);

	}

err:
	PKCS7_free(P7_sign);
	return -1;

}

//签名校验
int PKCS7_SignVerify_Me(char *Base64Sign);
int PKCS7_SignVerify_Me(char *Base64Sign)
{
	//Base64解码操作
    unsigned char lc_Sign_Der[DATA_LEN];
	int li_signB64_len=strlen(Base64Sign);
	int li_len=EVP_DecodeBlock (lc_Sign_Der, Base64Sign, li_signB64_len);
	printf("befor len=%d\n",li_signB64_len);
	while(Base64Sign[--li_signB64_len]== '=')
	li_len--;

	printf("after len=%d\n",li_len);

    //Der2Asni
    PKCS7*p7_Decode_Sign = d2i_PKCS7(NULL, &lc_Sign_Der, li_len);
    if(!p7_Decode_Sign)
    {
        printf("build p7 sign object failed \n");
        return -1;
    }

	//验签
    int li_code = PKCS7_signatureVerify_Me(p7_Decode_Sign);
    if(li_code == -1)
    {
        printf("signatureVerify failed \n");
        return -1;
    }

}

//签名校验
int PKCS7_signatureVerify_Me(PKCS7 *p7_res_sign);
int PKCS7_signatureVerify_Me(PKCS7 *p7_res_sign)
{
	BIO * p7bio_AA = PKCS7_dataDecode(p7_res_sign, NULL,NULL,NULL);
	int len=BIO_ctrl_pending(p7bio_AA);
	if(len <= 0)
	{
		printf("get data length failed\n");
		return -1;
	}
	else
	{
		char decode_data_2[10240]={0};
		int write_len=BIO_read(p7bio_AA, decode_data_2,len);
		printf( "buffer data is %s /n",decode_data_2);
		//获得签名者信息stack
		STACK_OF(PKCS7_SIGNER_INFO) *sk = PKCS7_get_signer_info(p7_res_sign);
		int signCount=sk_PKCS7_SIGNER_INFO_num(sk);
		int li_num=0;
		for(li_num; li_num < sk_PKCS7_SIGNER_INFO_num(sk); li_num++)
		{
			//获得签名者信息
			PKCS7_SIGNER_INFO *signInfo = sk_PKCS7_SIGNER_INFO_value(sk,li_num);
			
			//获得签名者证书
			X509 *cert= PKCS7_cert_from_signer_info(p7_res_sign,signInfo);
			//验证签名
			if(PKCS7_signatureVerify(p7bio_AA, p7_res_sign, signInfo, cert) != 1)
			{
				printf("usignatureVerify Erri/n");
				return -1;
			}
		}
	}
	
	BIO_free(p7bio_AA);
	return 1;
}

//ASNI转DER编码
int Asni2Der(PKCS7* p7, int *li_len, unsigned char**p_str);
int Asni2Der(PKCS7* p7, int *li_len, unsigned char**p_str)
{   
    unsigned char*der = NULL;
    unsigned char*derTmp;
    int len = i2d_PKCS7(p7,NULL);
	der=(unsigned char*)malloc(len);
    if(der == NULL) return -1;
	printf("der code length=%d\n",len);
	memset(der,0,len);
	derTmp=der;
	i2d_PKCS7(p7,(unsigned char **)&derTmp);
    *p_str = der;
    *li_len = len;
    return 0;
}

//测试加签延签流程
int Sign_SignVerify(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, int flags);
int Sign_SignVerify(X509 *signcert, EVP_PKEY *private_key, STACK_OF(X509) *certs, int flags)
{
    char src_data[DATA_LEN];
    memset(src_data, 0x00, DATA_LEN);
    memcpy(src_data, "this is a secret", 16);

	unsigned char Base64Sign[DATA_LEN * 2];
    memset(Base64Sign, 0x00, sizeof(Base64Sign));
    BIO*sign_data=BIO_new(BIO_s_mem());
    BIO_puts(sign_data, src_data);

    //加签
    if (PKCS7_sign_Me(signcert, private_key, certs, sign_data, flags, Base64Sign) == -1)
	{
		return -1;
	}

	if (PKCS7_SignVerify_Me(Base64Sign) == -1)
	{
		return -1;
	}

	return 0;
}

//
//测试签名+数字信封
//int Sign_Enveloped();


int main(int argc, char*argv[])
{
	if(argc < 2)
	{
		printf("low argument\n");
		return -1;
	}
	
    int li_chose = argv[0];

    //读取证书和私钥
    char certfile[256];
	memset(certfile,0x00,sizeof(certfile));
	sprintf(certfile,"/home/wdy/CC/test.pem");

    BIO *infile, *p7bio;
	STACK_OF(X509) *certs = NULL;
	X509 *signcert=NULL;
	const EVP_CIPHER *cipher = NULL;
	if(!(infile=BIO_new_file(certfile,"r")))
		printf("BIO_new_file-ERROR/n");
	if(!(signcert=PEM_read_bio_X509(infile,NULL,NULL,NULL)))
		printf("PEM_read_bio_X509-ERROR/n");
	if(!certs) certs=sk_X509_new_null();
	sk_X509_push(certs,signcert);
	BIO_free(infile);

    EVP_PKEY* private_key = NULL;
    FILE* fp = fopen(certfile, "r");
	if (fp == NULL) 
		return -1;
    else
    {
        private_key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
	    fclose (fp);
    }

	int li_code = 0;
	if(li_chose == 1)
	{
		li_code= Sign_SignVerify(signcert, private_key, certs, PKCS7_NOSMIMECAP | PKCS7_BINARY);
	}
	else if(li_chose == 2)
	{

	}
	else if(li_chose == 3)
	{

	}
	else if(li_chose == 4)
	{

	}
	else
	{
		printf("ERROR!!!!!!\n");
	}
	
    
}
#if 0
int main()
{
	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();  
	
	char certfile[256];
	memset(certfile,0x00,sizeof(certfile));
	sprintf(certfile,"/home/wdy/CC/test.pem");
	char src_data[10240];
	memset(src_data, 0x00,sizeof(src_data));
	memcpy(src_data, "AAAAAAAAAAAAAAAAA", 17);
	char Base64Enevloped[10240]={0};
	BIO *infile, *p7bio;
	STACK_OF(X509) *certs = NULL;
	X509 *signcert=NULL;
	const EVP_CIPHER *cipher = NULL;
	if(!(infile=BIO_new_file(certfile,"r")))
		printf("BIO_new_file-ERROR/n");
	if(!(signcert=PEM_read_bio_X509(infile,NULL,NULL,NULL)))
		printf("PEM_read_bio_X509-ERROR/n");
	if(!certs) certs=sk_X509_new_null();
	sk_X509_push(certs,signcert);
	BIO_free(infile);
	if(!cipher) 
	{
	#ifndef OPENSSL_NO_DES
		cipher=EVP_des_ede3_cbc();
	#else
		printf("No cipher selected\n");
	#endif
	}
	
	BIO*p7_data_sign=BIO_new(BIO_s_mem());
	BIO_puts(p7_data_sign, src_data);
	
	FILE* fp = fopen (certfile, "r");
	if (fp == NULL) 
		return -1;
 
	/* Read private key */
	EVP_PKEY* private_key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
	fclose (fp);

	//构造签名
	PKCS7* P7_sign =  PKCS7_sign_Me(signcert, private_key, certs, p7_data_sign, PKCS7_DETACHED | PKCS7_NOSMIMECAP | 0x80);
	if(!P7_sign)
    {
		return -1;
	}		
	
	//ASN1转DER编码
	int len = i2d_PKCS7(P7_sign,NULL);
	unsigned char*der_sign = (unsigned char*)malloc(len);
	printf("sign der code length=%d\n",len);
	memset(der_sign,0,len);
	unsigned char*derTmp = der_sign;
	i2d_PKCS7(P7_sign,(unsigned char **)&derTmp);
	
	/*----测试打印sign----------------------begin-*/
	//转Base64编码(可见字符)
	char Base64encode[10240];
	memset(Base64encode, 0x00, sizeof(Base64encode));
	EVP_EncodeBlock(Base64encode, der_sign, len);
	printf("base lenth =%d, base der[%s]\n",strlen(Base64encode), Base64encode);
	/*----测试打印sign------------------------end-*/
	
	//DER签名数据作为信封的内容,再次加密
	
	BIO*p7_data_enc = BIO_new(BIO_s_mem());
	BIO_write(p7_data_enc, Base64encode, strlen(Base64encode));
	
	//释放空间
	BIO_free(p7_data_sign);
	PKCS7_free(P7_sign);
	free(der_sign);

	
	//数字信封加密
	PKCS7* p7_enveloped=PKCS7_encrypt(certs, p7_data_enc, cipher, 0X80);   
	if(!p7_enveloped)
	{
		printf("PKCS7 encrypt failed\n");
		return-1;
	}
	
	
	//ASN1转DER编码
	len = i2d_PKCS7(p7_enveloped,NULL);
	unsigned char*der=(unsigned char*)malloc(len);
	printf("der code length=%d\n",len);
	memset(der,0,len);
	derTmp=der;
	i2d_PKCS7(p7_enveloped,(unsigned char **)&derTmp);
	//转Base64编码(可见字符)
	EVP_EncodeBlock(Base64Enevloped,der,len);
	
	printf("base lenth =%d,base der[%s]\n",strlen(Base64Enevloped), Base64Enevloped);
	printf("PKCS7 签名+数字信封successed\n");
	
	//需要释放空间
	free(der);
	PKCS7_free(p7_enveloped);
	BIO_free(p7_data_enc);
	
	
	//从Base64编码的密文开始解密--------------------------------------------
	//base64编码转换->DER编码
	char enevlop_dec[10240]={0};
	int len_tmp=strlen(Base64Enevloped);
	len=EVP_DecodeBlock (enevlop_dec,Base64Enevloped,len_tmp);
	printf("befor len=%d\n",len);
	while(Base64Enevloped[--len_tmp]== '=')
	len--;
	
	printf("after len=%d\n",len);
	const unsigned char*p;
	p=enevlop_dec;
	
	//由DER编码的数据解析PKCS7信封
	PKCS7*p7=d2i_PKCS7(NULL,&p,len);
	if(!p7)
	{
		printf("Could not build PKCS7 struct\n");return -1;
	}

    FILE* fd=NULL;
    EVP_PKEY *rsa_privk=NULL;
	if((fd=fopen (certfile,"r")))
	{
	   rsa_privk = PEM_read_PrivateKey (fd,NULL,NULL,NULL);
	   if(!rsa_privk)
	   {
	   	   printf("Could not read private RSA key\n");
		   fclose(fd);
		   return-1;
	   }
	}
	
	//PKCS7_decrypt解密信封
	BIO*out_data=BIO_new(BIO_s_mem());
	
	if(PKCS7_decrypt(p7, rsa_privk, signcert, out_data, 0X80)>0)
		printf("prcs7_decrypt enevlod successed\n");
	
	int	len_l=BIO_ctrl_pending(out_data);
	char *out = NULL;
	out=(char *)OPENSSL_malloc(len_l);
	if(out == NULL)
	{
		printf("Could not malloc memory\n");
		return -1;
	}
	int len_ll=BIO_read(out_data,out,len_l);
	printf("解析签名BASE64数据:[%s], lenth = %d\n",out,len_l);
	
	//base64编码转换->DER编码
	char sign_dec[10240];
	len_tmp=strlen(out);
	len=EVP_DecodeBlock (sign_dec,out,len_tmp);
	printf("decode sign befor len=%d\n",len);
	while(out[--len_tmp]== '=')
	len--;
	
	printf("decode sign after len=%d\n",len);
	p=sign_dec;
	
	//从信封中解密出来签名数据,
	PKCS7*p7_res_sign=d2i_PKCS7(NULL, &sign_dec, len_ll);
	//解Base64再去验签
	
	//OPENSSL_free(out);
	//BIO_free(out_data);
	
	if(!p7_res_sign)
	{
		printf("Could not build PKCS7 sign struct\n");
		return -1;
	}
	int li_code = PKCS7_signatureVerify_Me(p7_res_sign);
	if(li_code == -1)
	{
		return -1;
	}
	return 1;
}
#endif





























































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值