c语言实现用openssl进行数据摘要和签名,sha512 with rsa

因协议要求要在https的消息头里面附带消息体的摘要信息,所以研究了下sha512散列算法和rsa加密算法,下面是用openssl实现的数据sha512算法摘要和rsa签名

#include 
#include 
#include 
#include 
#include  
#include  

#define PUBLIC_KEY_PATH ("/hd1/program/config/ca/client_sunell_public.pem")
#define PRIVATE_KEY_PATH ("/hd1/program/config/ca/client_sunell_private.pem")


void printHash(unsigned char *md, int len)
{

	int i = 0;
    for (i = 0; i < len; i++)
	{
		printf("%02x", md[i]);
	}

	printf("\n");
}


/*读取私钥*/
RSA* ReadPrivateKey(char* p_KeyPath)
{	
	FILE *fp = NULL; 
	char szKeyPath[1024];
	RSA  *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;
	
	printf("PrivateKeyPath[%s] \n", p_KeyPath);

	/*	打开密钥文件 */
	if(NULL == (fp = fopen(p_KeyPath, "r")))
	{
		printf( "fopen[%s] failed \n", p_KeyPath);
		return NULL;
	}
	/*	获取私密钥 */
	priRsa = PEM_read_RSAPrivateKey(fp, NULL, NULL,NULL);
	if(NULL == priRsa)
	{
		ERR_print_errors_fp(stdout);
		printf( "PEM_read_RSAPrivateKey\n");
		fclose(fp);
		return NULL;
	}
	fclose(fp);
	
	pOut = priRsa;
	return pOut;
}

/*读取公匙*/
RSA* ReadPublicKey(char* p_KeyPath)
{	
	FILE *fp = NULL; 
	char szKeyPath[1024];
	RSA  *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;
	
	printf("PublicKeyPath[%s]\n", p_KeyPath);

	/*	打开密钥文件 */
	if(NULL == (fp = fopen(p_KeyPath, "r")))
	{
		printf( "fopen[%s] \n", p_KeyPath);
		return NULL;
	}
	/*	获取私密钥 */
	if(NULL == (priRsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL,NULL)))
	{
		printf( "PEM_read_RSAPrivateKey error\n");
		fclose(fp);
		return NULL;
	}
	fclose(fp);

	pOut = priRsa;
	return pOut;
}

int main()
{
        char *ct = "55dsd421fd4df1x21c1d4sd21sd51s5";
	char *buf;   
	char *buf2;
  	RSA *pubKey;
  	RSA *privKey;
	int len;

	buf = malloc(520);
        buf2 = malloc(520);

	//对数据进行sha512算法摘要
	SHA512_CTX c;
	unsigned char md[SHA512_DIGEST_LENGTH];

	SHA512((unsigned char *)ct, strlen(ct), md);
	printHash(md, SHA512_DIGEST_LENGTH);

	/*下面这个方法和上面方法得到结果是一样的*/
	//SHA512_Init(&c);
	//SHA512_Update(&c, ct, strlen(ct));

	//SHA512_Final(md, &c);
	//OPENSSL_cleanse(&c, sizeof(c));

	//printHash(md, SHA512_DIGEST_LENGTH);

        privKey = ReadPrivateKey(PRIVATE_KEY_PATH);
        if (!privKey) 
	{  
		ERR_print_errors_fp (stderr);    
		exit (1);  
	}

        pubKey = ReadPublicKey(PUBLIC_KEY_PATH);  
	if(!pubKey)
	{
	   RSA_free(privKey);   
       printf("Error: can't load public key");
	   exit(1);
	}

        /*签名:私钥加密*/
	int nRet = RSA_sign(NID_sha512, md, SHA512_DIGEST_LENGTH, buf, &nOutLen, privKey);
	if(nRet != 1)
	{
		printf("RSA_sign err !!! \n");    
		exit(1);  
	}
	printf("RSA_sign len = %d:", nOutLen);
	printHash(buf, nOutLen);
    
	//len = RSA_private_encrypt(SHA512_DIGEST_LENGTH, md, buf,     
        //privKey,RSA_PKCS1_PADDING);
	//if (len != 256)
	//{
	    //printf("Error: ciphertext should match length of key len = %d \n", len);
	    //exit(1);
	//}
	
	//printf("RSA_private_encrypt:");
	//printHash(buf, strlen(buf));

	/*公钥解密*/
	//RSA_public_decrypt(len, (const unsigned char*)buf, (unsigned char*)buf2, 
        //pubKey,RSA_PKCS1_PADDING);	
	//printf("RSA_public_decrypt:");
	//printHash(buf2, strlen(buf2));

	RSA_free(privKey);
	RSA_free(pubKey);
	free(buf);
	free(buf2);
	
    return 0;
}

执行结果:
fbf9cfab10a4e7a964c109da53f9e14888fa85b9b82ddfb748991b4c470ee54a8883cb298db1a170abcf2b75ed7e187710b20f2cbc1c70a619e8e7284230177d
PrivateKeyPath[/hd1/program/config/ca/client_sunell_private.pem] 
PublicKeyPath[/hd1/program/config/ca/client_sunell_public.pem]

RSA_private_encrypt:acff90f36d7220a0f1f0485d209134e75c5b39e58d082d0591fb05898519188b8c4ba87d9fb7a4ac23
RSA_public_decrypt:fbf9cfab10a4e7a964c109da53f9e14888fa85b9b82ddfb748991b4c470ee54a8883cb298db1a170abcf2b75ed7e187710b20f2cbc1c70a619e8e7284230177d

 

你可能感兴趣的:(技术,c)