CryptoAPI与openssl数字签名与验证交互

昨天写过了RSA非对称加密解密的交互方式,

其实数字签名也是RSA非对称加密,只不过用私钥加密的,再加上个hash摘要

CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互已经提到关于证书和私钥的数据以及对象获取,这里就不再重复讨论


1.openssl的签名及验证

void opensslSigner::sign(EVP_PKEY* evpKey,BYTE** signValue,unsigned int &signLen,BYTE* text,int textLen)
{
	EVP_MD_CTX mdctx;   //摘要算法上下文变量  
	 
	if(evpKey == NULL)  
	{  
		printf("EVP_PKEY_new err\n");  
		return;  
	}  
	
	//以下是计算签名的代码  
	EVP_MD_CTX_init(&mdctx);        //初始化摘要上下文  
	if(!EVP_SignInit_ex(&mdctx,EVP_md5(),NULL)) //签名初始化,设置摘要算法  
	{  
		printf("err\n");  
		EVP_PKEY_free(evpKey);  
		return;  
	}  
	if(!EVP_SignUpdate(&mdctx,text,textLen)) //计算签名(摘要)Update  
	{  
		printf("err\n");  
		EVP_PKEY_free(evpKey);  
		return;  
	}  
	if(!EVP_SignFinal(&mdctx,*signValue,&signLen,evpKey))  //签名输出  
	{  
		printf("err\n");  
		EVP_PKEY_free(evpKey);  
		return;  
	}  
	printf("消息\"%s\"的签名值是:\n",text);  
	printByte(*signValue,signLen);
	printf("\n");  
	EVP_MD_CTX_cleanup(&mdctx);  

}

void opensslSigner::verify(EVP_PKEY* evpKey,BYTE* text,unsigned int textLen,BYTE* signValue,unsigned int signLen)
{
	ERR_load_EVP_strings();
	EVP_MD_CTX mdctx;   //摘要算法上下文变量  
	EVP_MD_CTX_init(&mdctx);    //初始化摘要上下文  
	if(!EVP_VerifyInit_ex(&mdctx, EVP_md5(), NULL)) //验证初始化,设置摘要算法,一定要和签名一致  
	{  
		printf("EVP_VerifyInit_ex err\n");  
		EVP_PKEY_free(evpKey);  
		return;  
	}  
	if(!EVP_VerifyUpdate(&mdctx, text, textLen)) //验证签名(摘要)Update  
	{  
		printf("err\n");  
		EVP_PKEY_free(evpKey);  
		return;  
	}  
	if(!EVP_VerifyFinal(&mdctx,signValue,signLen,evpKey))  
	{  
		printf("verify err\n");  
		EVP_PKEY_free(evpKey);  
		EVP_MD_CTX_cleanup(&mdctx);  
		return;
	}  
	else  
	{  
		printf("验证签名正确.\n");  
	}  
	//释放内存  
	EVP_PKEY_free(evpKey);  
	EVP_MD_CTX_cleanup(&mdctx);  
}

2.CryptoAPI的签名验证

依然是私钥的问题,没时间再去尝试导入私钥,暂且只写验证

因为也是RSA加密,所以同样要注意字节排列方式,具体看RSA加密的交互部分

void verify(HCRYPTPROV hProv,PCCERT_CONTEXT cert,BYTE* text,unsigned long len,BYTE* signValue,unsigned long signLen)
{
        //反序与openssl一致
	for(int i = 0 ; i < signLen / 2;i++)
	{
		BYTE temp = signValue[i];
		signValue[i] = signValue[signLen - i - 1];
		signValue[signLen - i - 1] = temp;
	}

	// 创建离散对象    
	HCRYPTHASH hHash = NULL;    
	if(!CryptCreateHash(    
		hProv,                        // 容器句柄     
		CALG_MD5,                    // 算法标识    
		NULL,                        // 算法使用的Key    
		0,                            // 算法标识    
		&hHash))                    // 返回的HASH对象    
	{    
		printf("CryptCreateHash error:0X%x.\n",GetLastError());
		return;
	}    
    
	// 计算数据摘要    
	if(CryptHashData(hHash, text, len, 0) == 0)    
	{    
		printf("CryptHashData error:0X%x.\n",GetLastError());
		return;
	}    


	if(cert == NULL)    
	{    
		printf("pCertContext == NULL:0X%x.\n",GetLastError());
		return;
	}    
	//获取公钥句柄  
	HCRYPTKEY hPubKey;    
	if(!CryptImportPublicKeyInfo(hProv, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, &hPubKey))    
	{    
		printf("CryptImportPublicKeyInfo error:0X%x.\n",GetLastError());
		return;
	}    
	//验证签名  
	if(!CryptVerifySignature(hHash, signValue, signLen, hPubKey, NULL, 0))    
	{    
		printf("CryptVerifySignature error:0X%x.\n",GetLastError());
		return;
	}    
	cout << "sign verify successfully" << endl;
}



你可能感兴趣的:(算法,加密,解密,null,byte)