突然找到數年前寫的這段代碼,當是因為對密碼學幾乎不怎么了解踩了一些坑,現在開源出來方便大家直接利用。
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