使用openssl实现ECDSA签名以及验证功能(附完整测试源码)

突然找到数年前写的这段代码,当是因为对密码学几乎不怎么了解踩了一些坑,现在开源出来方便大家直接利用。

ECDSA的全名是Elliptic Curve DSA,也就是椭圆曲线DSA,由于椭圆曲线的复杂性是的其具备良好的安全性,也就是说无法从公钥计算出私钥。

签名过程分为以下两步:
第一步:对于一段指定的字符串,首先对其做消息摘要。在示例代码中采用256bit的摘要,也就是以下部分:

EVP_MD_CTX md_ctx;
EVP_MD_CTX_init(&md_ctx);
EVP_DigestInit(&md_ctx,EVP_sha256());
EVP_DigestUpdate(&md_ctx, (const void*)szBufferData,nBufferData);
EVP_DigestFinal(&md_ctx, digest, &dgst_len);

第二步:通过产生一个随机数,记为K,然后利用其计算出两个大数,记为R和S。将R和S拼在一起就是对消息摘要的签名数据。

由于K是随机产生,所以经常出现同一段数据,同一个私钥,产生的签名文件不一样。其实这也很容易理解,因为每次加密K也未必一样。

 

那么验证的过程就是从签名数据中分离出R和S,然后利用公钥和S计算出R,如果和接收的R相等,那表示验证成功,否则失败。

 

以上是简单的介绍签名以及验证过程,具体可以参见详细代码。其中包括产生公私钥对并保存文件,以及对数据或者文件签名,验证过程。具体实现代码我已经封装到指定类当中了,使用示例如下:

 1 CECDSAManager ecdsaManager;
 2     if (ECDSA_SUCESS == ecdsaManager.CreateECDSAKey("E:"))
 3     {
 4         if (ECDSA_SUCESS == ecdsaManager.ECDSASignFileToLicenceFile("E://ec_key.pem","D://ffmpeg解码.JPG","D://1.sig"))
 5         {
 6             if (ECDSA_SUCESS == ecdsaManager.ECDSAVerifyLicenceFile("E://public.pem","D://ffmpeg解码.JPG","D://1.sig"))
 7             {
 8                 printf("Sucess \n");
 9             }
10         }
11     }


以下代码可以在VS2010中编译运行,源码下载:ECDSATestProj.zip

posted @ 2016-11-18 15:25  繁星jemini  阅读(6900)  评论(0编辑  收藏  举报