基于Crypto++密码库的ECIES和ECDSA算法的联合使用

使用背景

毕设要求使用ECC椭圆曲线加密算法为用户信息加密,并数字签名。鉴于设计要求,ECIES的公私钥同样为ECDSA的公私钥。数字签名是后加部分。在已完成的设计部分中,ECIES的公私钥已将转化为std::string类型,在最小改动前提下,做出程序。

软件平台

  • Crypto++ – 7.0.0
  • MacBook pro – 10.13.4
  • GCC – Configured with: –prefix=/Applications/Xcode.app/Contents/Developer/usr –with-gxx-include-dir=/usr/include/c++/4.2.1;Apple LLVM version 9.1.0 (clang-902.0.39.1)
  • 设计语言 – C++
  • 用前必读

    发现过程

  • ECC公钥(第一组) – 3059301306072A8648CE3D020106082A8648CE3D0301070342000432AAB20C1C02D8844834D5AAC7E12814A53266AA5F0350190A9C1A9C43AA4178FFDC04D0785EE52676D061B5D836FEB34D766E710CE2196B5ADAF7876E805C01
  • ECC私钥(第一组)- 3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420C044B0620BAC02DA779426C1292A6398AA7EB99D9F624E9921186211AFFB6117
  • ECC公钥(第二组)- 3059301306072A8648CE3D020106082A8648CE3D030107034200045EF50890EDC7FAAA2420533FA500AC897236DDE114A4FE7215B48F908585208E3DD9F1CEB1D923EEDB3C95027D82FE6AF64F82CB61631DEB7B68028899D7328C
  • ECC私钥(第二组)- 3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420FD9BB947E95A503645CAD68DC70E21E3D04AF2C52206B9057ED52D94299E93BE
  • ECC公钥(第三组)- 3059301306072A8648CE3D020106082A8648CE3D0301070342000419514747D4D4F91C484DC529D1695E05D8383D04EB6D84A0BF40C4641CB3490FF17BF5ECA97A7C0F325D62C5EE2180D9C5ABC977CBEE1A40B45F5B32EB1F61F3
  • ECC私钥(第三组)- 3041020100301306072A8648CE3D020106082A8648CE3D0301070427302502010104203DB7FB2335C3368485C1A51AD9F36FA3FF4B2BC187D0D3FAE40977066EE74116
  • 是的,你可能发现了。ECC公钥的前54个字符是相通的,每次变化的只是后面的。同理,ECC私钥每次变化的也只是前70个字符,我猜想,是不是后面变化的才是公私钥。经过尝试,可以使用充当ECDSA的公私钥。

    ECIES加解密Demo

    该Demo是我从 上找到的, 上有很多Demo,但是有些我发现用不了,在可用的Demo中最符合我需求的是这个,同时,我稍微进行了更改。如有侵权,告知必删。

    #include <iostream>#include "eccrypto.h"#include "osrng.h"#include "oids.h"#include "hex.h"#include "filters.h"#ifndef ECC_ENCRYPTION_ALGORITHM_H_#define ECC_ENCRYPTION_ALGORITHM_H_#include<string>class EccEncryption{public: /// This method is used to generate keys for ECC encryption algorithm /// /// param[in] uiKeySize, length of key /// param[out] sPrivateKey, private key /// param[out] sPublicKey, public key void GenerateEccKeys(unsigned int uiKeySize, std::string& sPrivateKey, std::string& sPublicKey); /// This method is used to encrypt the input message using public key /// /// param[in] sPublicKey, public key generated by the first method /// param[out] sMsgToEncrypt, message to encryppt /// return the message encrypted using the input public key std::string Encrypt(const std::string& sPublicKey, const std::string& sMsgToEncrypt); /// This method is used to decrypt the input message using private key /// /// param[in] sPrivateKey, private key used to decrypt the cipher text /// param[in] sMsgToDecrypt, cipher text used to decrypt to get the plain text /// return decrypted plain text std::string Decrypt(const std::string& sPrivateKey, const std::string& sMsgToDecrytp);};#endifvoid EccEncryption::GenerateEccKeys(unsigned int uiKeySize, std::string& sPrivateKey, std::string& sPublicKey){ using namespace CryptoPP; // Random pool, the second parameter is the length of key // 随机数池,第二个参数是生成密钥的长 AutoSeededRandomPool rnd(false, 256); ECIES<ECP>::PrivateKey privateKey; ECIES<ECP>::PublicKey publicKey; // Generate private key privateKey.Initialize(rnd, ASN1::secp256r1()); // Generate public key using private key privateKey.MakePublicKey(publicKey); ECIES<ECP>::Encryptor encryptor(publicKey); HexEncoder pubEncoder(new StringSink(sPublicKey)); publicKey.DEREncode(pubEncoder); pubEncoder.MessageEnd(); ECIES<ECP>::Decryptor decryptor(privateKey); HexEncoder prvEncoder(new StringSink(sPrivateKey)); privateKey.DEREncode(prvEncoder); prvEncoder.MessageEnd();}std::string EccEncryption::Encrypt(const std::string& sPublicKey, const std::string& sMsgToEncrypt){ using namespace CryptoPP; // If to save the keys into a file, FileSource should be replace StringSource StringSource pubString(sPublicKey, true, new HexDecoder); ECIES<ECP>::Encryptor encryptor(pubString); // Calculate the length of cipher text size_t uiCipherTextSize = encryptor.CiphertextLength(sMsgToEncrypt.size()); std::string sCipherText; sCipherText.resize(uiCipherTextSize); RandomPool rnd; encryptor.Encrypt(rnd, (byte*)(sMsgToEncrypt.c_str()), sMsgToEncrypt.size(), (byte*)(sCipherText.data())); return sCipherText;}std::string EccEncryption::Decrypt(const std::string& sPrivateKey, const std::string& sMsgToDecrytp){ using namespace CryptoPP; StringSource privString(sPrivateKey, true, new HexDecoder); ECIES<ECP>::Decryptor decryptor(privString); auto sPlainTextLen = decryptor.MaxPlaintextLength(sMsgToDecrytp.size()); std::string sDecryText; sDecryText.resize(sPlainTextLen); RandomPool rnd; decryptor.Decrypt(rnd, (byte*)sMsgToDecrytp.c_str(), sMsgToDecrytp.size(), (byte*)sDecryText.data()); return sDecryText;}int main(){ std::string sStrToTest = std::string("Hello world. This is an example of Ecc encryption algorithm of Crypto++ open source library."); EccEncryption ecc; std::string sPrivateKey, sPublicKey; ecc.GenerateEccKeys(1024, sPrivateKey, sPublicKey); std::cout << "Generated private key is : "<< std::endl; std::cout << sPrivateKey << std::endl; std::cout << "***********************************************************" << std::endl; std::cout << "Generated public key is : "<< std::endl; std::cout << sPublicKey << std::endl; std::cout << "***********************************************************" << std::endl; std::cout << "The message to be encrypted is : " << std::endl; std::cout << sStrToTest << std::endl; std::cout << "***********************************************************" << std::endl; std::string sEncryptResult = ecc.Encrypt(sPublicKey, sStrToTest); std::cout << "The result of encrypt is : " << std::endl; std::cout << sEncryptResult << std::endl; std::cout << "***********************************************************" << std::endl; std::string sDecryptResult = ecc.Decrypt(sPrivateKey, sEncryptResult); std::cout << "The result of decrypt is : " << std::endl; std::cout << sDecryptResult << std::endl; std::cout << "***********************************************************" << std::endl; return 0;}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126

    ECIES-ECSDSA联合使用Demo

    /*auteur:GXCSDN:GuoXuan_CHN*/#include <fstream>#include <string>#include <iostream>#include "eccrypto.h"#include "osrng.h"#include "oids.h"#include "hex.h"#include "filters.h"#include "des.h"using namespace std; CryptoPP::ECIES<CryptoPP::ECP>::PrivateKey ePrivateKey; CryptoPP::ECIES<CryptoPP::ECP>::PublicKey ePublicKey;string sPrivateKey, sPublicKey;void GenerateEccKeys(){ using namespace CryptoPP; // Random pool, the second parameter is the length of key // 随机数池,第二个参数是生成密钥的长 AutoSeededRandomPool rnd(false, 256); // Generate private key // 生成私钥 ePrivateKey.Initialize(rnd, ASN1::secp256r1()); // Generate public key using private key // 用私钥生成密钥 ePrivateKey.MakePublicKey(ePublicKey); HexEncoder pubEncoder(new StringSink(sPublicKey)); ePublicKey.DEREncode(pubEncoder); pubEncoder.MessageEnd(); HexEncoder prvEncoder(new StringSink(sPrivateKey)); ePrivateKey.DEREncode(prvEncoder); prvEncoder.MessageEnd();}string signe (string message){ std::string signature=""; //数字签名过程 CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::PrivateKey privateKey; std::string exp = sPrivateKey.substr(70); CryptoPP::HexDecoder decoder; decoder.Put((CryptoPP::byte *)&exp[0], exp.size()); decoder.MessageEnd(); CryptoPP::Integer x; x.Decode(decoder, decoder.MaxRetrievable()); privateKey.Initialize(CryptoPP::ASN1::secp256r1(), x); CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::Signer signer( privateKey ); CryptoPP::AutoSeededRandomPool prng; //签名结果 signature = ""; CryptoPP::StringSource s( message, true /*pump all*/, new CryptoPP::SignerFilter( prng, signer, new CryptoPP::StringSink( signature ) ) // SignerFilter ); // StringSource return signature; //签名过程结束}bool VerifierSignature(string signature,string message){ std::string pt=""; //验签过程 CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA1>::PublicKey publicKey; pt = sPublicKey.substr(54); CryptoPP::HexDecoder decoder; decoder.Put((CryptoPP::byte *)&pt[0], pt.size()); decoder.MessageEnd(); CryptoPP::ECP::Point q; size_t len = decoder.MaxRetrievable(); q.identity = false; q.x.Decode(decoder, len/2); q.y.Decode(decoder, len/2); publicKey.Initialize( CryptoPP::ASN1::secp256r1(), q ); CryptoPP::ECDSA<CryptoPP::ECP,CryptoPP::SHA1>::Verifier verifier(publicKey); // Result of the verification process bool result = false; CryptoPP::StringSource ss( signature+message, true /*pump all*/, new CryptoPP::SignatureVerificationFilter( verifier, new CryptoPP::ArraySink((CryptoPP::byte *)&result, sizeof(result) ) ) ); return result;}int main(){ std::string message = "Yoda said, Do or do not. There is no try."; std::string signature=""; bool result = false; GenerateEccKeys(); signature = signe (message); result = VerifierSignature(signature,message); cout << "****** tester la bon*****" << endl; cout << result << endl; result = VerifierSignature(signature,"1234567890"); cout << "****** tester la mauvais*****" << endl; cout << result << endl;}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139

    编译指令

    该指令为在我本机上使用的指令,请合理更改

    g++ Demo_ECDSA.cpp -g -o prog -I /usr/local/include/cryptopp -lcryptopp

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2018年5月2日
    下一篇 2018年5月2日

    相关推荐