使用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