openssl 生成摘要、签名和验签接口使用

1、生成摘要

int getDigest(const char* source, int source_len, unsigned char *digest_data, unsigned int *digest_len)
{
	EVP_MD_CTX *mdctx;
	if((mdctx = EVP_MD_CTX_create()) == NULL) {
		return -1;
	}
    
	if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) {
		return -1;
	}

	if(1 != EVP_DigestUpdate(mdctx, source, source_len)) {
		return -1;
	}
    
	if(1 != EVP_DigestFinal_ex(mdctx, digest_data, digest_len)) {
		return -1;
	}
   
	EVP_MD_CTX_destroy(mdctx);
	
	return 0;
}


2、签名

int signData(EVP_PKEY * key, unsigned char *data, unsigned int data_len, 
                     unsigned char *sign, unsigned int *sign_len)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
	const EVP_MD* digestAlg = EVP_sha256();
    
	if(1 != EVP_SignInit(ctx, digestAlg))
		goto err_exit;  

	if(1 != EVP_SignUpdate(ctx, data, data_len))
		goto err_exit;

	if(1 != EVP_SignFinal(ctx, sign, sign_len, key))
		goto err_exit;

    EVP_MD_CTX_free(ctx);

    return 0;
err_exit:
    EVP_MD_CTX_free(ctx);
    return -1;
    
}

3、验签

int verify(EVP_PKEY * key, unsigned char * sign_data, unsigned int sign_data_len, 
            unsigned char * original, unsigned int original_len)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
	const EVP_MD* digestAlg = EVP_sha256();

	if(1 != EVP_VerifyInit(ctx, digestAlg))
		goto err_exit; 

	if(1 != EVP_VerifyUpdate(ctx, original, original_len))
		goto err_exit;    

	if(1 != EVP_VerifyFinal(ctx, sign_data, sign_data_len, key))
		goto err_exit; 

	EVP_MD_CTX_free(ctx);

    return 0;
err_exit:
    EVP_MD_CTX_free(ctx);
    return -1;
}

二、demo

int main(void)
{	
    FILE *sfd = fopen("/home/opensslapi/pfx_pri.pem", "r");
    FILE *pfd = fopen("/home/opensslapi/pfx_pub.pem", "r");
    EVP_PKEY *sk = PEM_read_PrivateKey(sfd, NULL, NULL, NULL);
    EVP_PKEY *pk = PEM_read_PUBKEY(pfd, NULL, NULL, NULL);

    fclose(sfd);
    fclose(pfd);

	char src_data[64] = "123qwet";
    unsigned int sign_len = 0, digest_len = 0;
    unsigned char sign[512] = {0};
    unsigned char hash_str[512] = {0};


	getDigest(src_data, strlen(src_data), hash_src, &digest_len);

    signData(sk, src_data, strlen(src_data), sign, &sign_len);
    
    if(0 == verify(pk, sign, sign_len, src_data, strlen(src_data)))
        printf("verify success\n");
    else
        printf("verify failed\n");

	EVP_PKEY_free(sk);
	EVP_PKEY_free(pk);
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ECDSA(Elliptic Curve Digital Signature Algorithm)是一种基于椭圆曲线密码学的数字签名算法。OpenSSL库提供了ECDSA签名和验的函数。 ECDSA签名: 1. 生成ECDSA密钥对: ``` EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); EC_KEY_generate_key(key); ``` 2. 计算消息的哈希值: ``` unsigned char *msg = "Hello World"; unsigned char digest[SHA256_DIGEST_LENGTH]; SHA256(msg, strlen(msg), digest); ``` 3. 对消息哈希值进行签名: ``` unsigned char *signature; unsigned int signature_len; signature = (unsigned char *)malloc(ECDSA_size(key)); ECDSA_sign(0, digest, SHA256_DIGEST_LENGTH, signature, &signature_len, key); ``` 4. 将签名结果进行编码: ``` unsigned char *encoded_signature; unsigned int encoded_signature_len; encoded_signature = (unsigned char *)malloc(signature_len * 2 + 1); ECDSA_signature_encode(ECDSA_SIG_new(), signature, signature_len, encoded_signature, &encoded_signature_len); ``` ECDSA验: 1. 解码签名结果: ``` ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new(); unsigned char *encoded_signature = "304402202a24c7d48f6a..."; // 签名结果 unsigned int encoded_signature_len = strlen(encoded_signature); ECDSA_signature_decode(ecdsa_sig, encoded_signature, encoded_signature_len); ``` 2. 计算消息的哈希值: ``` unsigned char *msg = "Hello World"; unsigned char digest[SHA256_DIGEST_LENGTH]; SHA256(msg, strlen(msg), digest); ``` 3. 进行验: ``` int result = ECDSA_do_verify(digest, SHA256_DIGEST_LENGTH, ecdsa_sig, key); if (result == 1) { printf("Signature verified successfully.\n"); } else if (result == 0) { printf("Signature verification failed.\n"); } else { printf("Error occurred during signature verification.\n"); } ``` 完整的示例代码: ``` #include <openssl/ec.h> #include <openssl/ecdsa.h> #include <openssl/obj_mac.h> #include <openssl/sha.h> int main() { EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); // 选择椭圆曲线 EC_KEY_generate_key(key); // 生成密钥对 // 签名 unsigned char *msg = "Hello World"; unsigned char digest[SHA256_DIGEST_LENGTH]; SHA256(msg, strlen(msg), digest); // 计算哈希值 unsigned char *signature; unsigned int signature_len; signature = (unsigned char *)malloc(ECDSA_size(key)); ECDSA_sign(0, digest, SHA256_DIGEST_LENGTH, signature, &signature_len, key); // 进行签名 unsigned char *encoded_signature; unsigned int encoded_signature_len; encoded_signature = (unsigned char *)malloc(signature_len * 2 + 1); ECDSA_signature_encode(ECDSA_SIG_new(), signature, signature_len, encoded_signature, &encoded_signature_len); // 编码签名结果 // 验 ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new(); ECDSA_signature_decode(ecdsa_sig, encoded_signature, encoded_signature_len); // 解码签名结果 int result = ECDSA_do_verify(digest, SHA256_DIGEST_LENGTH, ecdsa_sig, key); // 进行验 if (result == 1) { printf("Signature verified successfully.\n"); } else if (result == 0) { printf("Signature verification failed.\n"); } else { printf("Error occurred during signature verification.\n"); } ECDSA_SIG_free(ecdsa_sig); EC_KEY_free(key); free(signature); free(encoded_signature); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值