毕设要求使用ECC椭圆曲线加密算法为用户信息加密,并数字签名。鉴于设计要求,ECIES的公私钥同样为ECDSA的公私钥。数字签名是后加部分。在已完成的设计部分中,ECIES的公私钥已将转化为std::string类型,在最小改动前提下,做出程序。
在中文程序员网站上,有关Crypto++的ECDSA的使用Demo很少。我是查看Crypto++官网上的维基百科中的使用介绍来写出的。本文章并非旨在教学,而是旨在记录,其中我所提供的Demo根据我自身需求有所更改。如果本文章不能帮助你,请查看Crypto++官网中您所需求的函数的使用方法。本文的使用方法是我偶然发现,并尝试出可用,但我并不知道原理,如果您放在您的程序中,出现任何问题,我不负任何责任
是的,你可能发现了。ECC公钥的前54个字符是相通的,每次变化的只是后面的。同理,ECC私钥每次变化的也只是前70个字符,我猜想,是不是后面变化的才是公私钥。经过尝试,可以使用充当ECDSA的公私钥。
该Demo是我从网上找到的,网上有很多Demo,但是有些我发现用不了,在可用的Demo中最符合我需求的是这个,同时,我稍微进行了更改。如有侵权,告知必删。
#include
#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
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);
};
#endif
void 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::PrivateKey privateKey;
ECIES::PublicKey publicKey;
// Generate private key
privateKey.Initialize(rnd, ASN1::secp256r1());
// Generate public key using private key
privateKey.MakePublicKey(publicKey);
ECIES::Encryptor encryptor(publicKey);
HexEncoder pubEncoder(new StringSink(sPublicKey));
publicKey.DEREncode(pubEncoder);
pubEncoder.MessageEnd();
ECIES::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::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::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;
}
/*
auteur:GX
CSDN:GuoXuan_CHN
*/
#include
#include
#include
#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include "hex.h"
#include "filters.h"
#include "des.h"
using namespace std;
CryptoPP::ECIES::PrivateKey ePrivateKey;
CryptoPP::ECIES::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::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::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::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::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;
}
该指令为在我本机上使用的指令,请合理更改
g++ Demo_ECDSA.cpp -g -o prog -I /usr/local/include/cryptopp -lcryptopp