C++ 在ECIE中使用以前生成的私钥
我想使用ECIES加密/解密数据,为此我使用cryptoppC++ 在ECIE中使用以前生成的私钥,c++,public-key-encryption,crypto++,elliptic-curve,C++,Public Key Encryption,Crypto++,Elliptic Curve,我想使用ECIES加密/解密数据,为此我使用cryptopp AutoSeededRandomPool prng; //get private key generated ECIES<ECP>::Decryptor d0(prng, ASN1::secp256r1()); PrintPrivateKey(d0.GetKey()); //get public key ECIES<ECP>::Encryptor e0(d0); PrintPublicKey(e0.Get
AutoSeededRandomPool prng;
//get private key generated
ECIES<ECP>::Decryptor d0(prng, ASN1::secp256r1());
PrintPrivateKey(d0.GetKey());
//get public key
ECIES<ECP>::Encryptor e0(d0);
PrintPublicKey(e0.GetKey());
//encrypt the message
string em0; // encrypted message
StringSource ss1 (message, true, new PK_EncryptorFilter(prng, e0, new StringSink(em0) ) );
//decrypt the message
string dm0; // decrypted message
StringSource ss2 (em0, true, new PK_DecryptorFilter(prng, d1, new StringSink(dm0) ) );
autoseedrandompool-prng;
//获取生成的私钥
ECIES::解密程序d0(prng,ASN1::secp256r1());
PrintPrivateKey(d0.GetKey());
//获取公钥
ECIES::加密机e0(d0);
PrintPublicKey(e0.GetKey());
//加密消息
字符串em0;//加密信息
StringSource ss1(消息,真,新PK_EncryptorFilter(prng,e0,新StringSink(em0));
//解密消息
字符串dm0;//解密消息
StringSource ss2(em0,真,新PK_解密过滤器(prng,d1,新StringSink(dm0));
其他一切都很好,但我想使用已经生成的“私钥”而不是随机生成的“私钥”来做上述相同的事情,这与上面的情况不同。我该怎么做
我尝试了以下代码,但它只是崩溃了
autoseedrandompool-prng;
std::string privatekeyString=“02C200102C180F9E6A4E7A2F58B86BC179478”;
CryptoPP::HexDecoder解码器;
decoder.Put((字节*)privatekeyString.data(),privatekeyString.size());
decoder.MessageEnd();
ECIES::解密程序d0;
d0.AccessKey().AccessGroupParameters().Initialize(ASN1::secp128r1());
崩溃点
//加载私钥
d0.AccessKey().Load(解码器);
PrintPrivateKey(d0.GetKey());
//获取公钥
ECIES::加密机e0(d0);
PrintPublicKey(e0.GetKey());
字符串em0;//加密信息
StringSource ss1(消息,真,新PK_EncryptorFilter(prng,e0,新StringSink(em0));
cout我遇到的问题是,您似乎不知道您拥有什么,并且您使用的一些参数与其他参数一起使用时是错误的。所以这几乎是一种暗中的刺杀
首先,您应该将磁盘操作包装在try/catch
中。I/O总是会导致问题,因此请务必捕获与iostream
内容相关的异常。您还应该捕获与密钥加载相关的Crypto++异常。这将在没有任何信息的情况下处理“崩溃”
因此,您的代码可能类似于:
try
{
// Read key from disk, load it into Crypto++ object
}
catch(const Exception& ex)
{
cerr << "Caught Crypto++ exception " << ex.what() << endl;
}
catch(const std::runtime_error& ex)
{
cerr << "Caught C++ runtime error " << ex.what() << endl;
}
而且它太大了,不能放在p-128
中。也许你应该这样做:
try
{
// Read key from disk, load it into Crypto++ object
}
catch(const Exception& ex)
{
cerr << "Caught Crypto++ exception " << ex.what() << endl;
}
catch(const std::runtime_error& ex)
{
cerr << "Caught C++ runtime error " << ex.what() << endl;
}
试试看
{
自动进料器和OMPOOL prng;
std::string exponent=“02C200102C180F9E6A4E7A2F58B5BE86BC179478”;
StringSource ss(指数,真/*pumpAll*/,新的十六进制解码器);
整数x;
x、 解码(ss,ss.MaxRetrievable(),整数::无符号);
//cout我将添加另一个答案,向您展示如何序列化私有指数和公共点,以防您在使用公共点时遇到问题。它还向您展示如何保存PrivateKeyInfo和SubjectPublicKeyInfo
其生成的输出类似于以下内容。您将需要修补程序。它不是库的一部分
$。/ecies-test.exe
私人指数
六角体:57E91FA3EF48706D07E56D8CB566204A4416B833EFB9687D75A37D572 EC42277
Base64:V+kfo+9ICG0H5W2MTWYGSKQWUPVUWH9DAN9VY7EINC=
Base64(URL安全):V-kfo-9ICG0H5W2MTWYGSKQWUPVUWH9DAN9VY7EINC=
耻骨点
十六进制:037142DE6143B6AD44C74135FE71222AC1406F541E53CB635112DE4928EC94763C
Base64:A3FC3mFDtq1Ex0E1/nEiKsFAb1QeU8tjURLeSSjslHY8
Base64(URL安全):A3FC3mFDtq1Ex0E1_nEiKsFAb1QeU8tjURLeSSjslHY8
私钥(PrivateKeyInfo)
305930106072A8648CE3D0200106082A8648CE3D030107034200047142DE6143B6AD44C74135FE71
222AC1406F541E53CB635112DE4928EC94763CFA903D9282691AE47A2D718297465EF44E905A89ED
2D4553ED1DF906A6E2383B
公钥(SubjectPublicKeyInfo)
3041020100301306072A8648CE3D0201006082A8648CE3D0301070427302502010101042057E91FA3EF
48706D07E56D8CB566204A4416B833EFB9687D75A37D572 EC42277
使用上面的private exponent和public point,以下功能可以正常工作:
字符串发布点(“A7EDDUXAA4/6kOZ8H+firJ95YtKZvDrPFmyVoisyBfuW”);
StringSource ss(pub_point,true,新base64解码器);
ECIES::加密机加密机;
encryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp256r1());
ECP::点-点;
encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point,ss,ss.MaxRetrievable());
encryptor.AccessKey().SetPublicElement(点);
encryptor.AccessKey().ThrowIfInvalid(prng,3);
ECIES::解密器解密器;
decryptor.AccessKey().Initialize(prng,ASN1::secp256r1());
const Integer&priv_exp=decryptor.GetKey().GetPrivateExponent();
SecByteBlock x(priv_exp.MinEncodedSize());
priv_exp.Encode(x,x.size());
字符串s1、s2、s3;
六角编码器f1(新StringSink(s1));
Base64F2编码器(新StringSink(s2));
Base64Url编码器f3(新StringSink(s3));
信道开关cs1;
cs1.AddDefaultRoute(f1);
cs1.AddDefaultRoute(f2);
cs1.AddDefaultRoute(f3);
ArraySource as1(x,x.size(),true/*pumpAll*/,新重定向程序(cs1));
cout根据建议,我已成功完成加密和解密。
如果有人愿意,下面是代码片段
解密
字符串解密(std::string encryptedMessage,std::string privateKeyExponent)
{
字符串解密消息;
尝试
{
自动进料器和OMPOOL prng;
//由于“privateKeyExponent”为base-64格式,请使用BASE64解码器
StringSource ss(privateKeyExponent,true/*pumpAll*/,新的CryptoPP::Base64解码器);
整数x;
x、 解码(ss,ss.MaxRetrievable(),整数::无符号);
ECIES::解密器-解密器;
//使用的曲线为secp256k1
//使用解码的私有指数值生成解密程序的访问密钥
decryptor.AccessKey().Initialize(ASN1::secp256k1(),x);
//检查解密器的访问密钥是否有效
bool valid=decryptor.AccessKey().Validate(prng,3);
如果(!有效)
decryptor.AccessKey().ThrowIfInvalid(prng,3);
不能“我尝试了以下代码,但它只是崩溃了…”-崩溃或错误是什么?请说明您从何处获得私钥,以及他们告诉您的。在编辑过程中,您需要使用base64解码器
,而不是HexDecoder
@jww。如何使用iv(initi)添加nonce
try
{
AutoSeededRandomPool prng;
std::string exponent="AsIAECwYD55qTnovWLW+hrwXlHg=";
StringSource ss(exponent, true /*pumpAll*/, new CryptoPP::HexDecoder);
Integer x;
x.Decode(ss, ss.MaxRetrievable(), Integer::UNSIGNED);
// cout << "Exponent: " << std::hex << x << endl;
ECIES<ECP>::Decryptor decryptor;
decryptor.AccessKey().Initialize(ASN1::secp128r1(), x);
bool valid = decryptor.AccessKey().Validate(prng, 3);
if(!valid)
{
cout<<"Exponent is not valid for P-128"<<endl;
return;
}
// throw Exception(CryptoPP::Exception::OTHER_ERROR, "Exponent is not valid for P-256");
// Or: decryptor.AccessKey().ThrowIfInvalid(prng, 3);
cout << "Exponent is valid for P-128" << endl;
PrintPrivateKey(decryptor.GetKey());
//get public key
ECIES<ECP>::Encryptor encryptor(decryptor);
PrintPublicKey(encryptor.GetKey());
string em0; // encrypted message
StringSource ss1(message, true, new PK_EncryptorFilter(prng, encryptor, new StringSink(em0) ) );
cout<<"encrypted msg: "<<em0<<" and its length: "<<em0.length()<<endl;
string dm0; // decrypted message
StringSource ss2 (em0, true, new PK_DecryptorFilter(prng, decryptor, new StringSink(dm0) ) );
cout <<"decrypted msg: "<< dm0<<" and its length: "<<dm0.length() << endl;
}
catch(const CryptoPP::Exception& ex)
{
std::cerr << ex.what() << endl;
}
std::string public_point="AsIAEFjzIcX+Kvhe8AmLoGUc8aYAEAwf5ecREGZ2u4RLxQuav/A=";
StringSource ss(public_point, true, new CryptoPP::HexDecoder);
ECIES<ECP>::Encryptor encryptor;
encryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp128r1());
ECP::Point point;
encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
cout << "X: " << std::hex << point.x << endl;
cout << "Y: " << std::hex << point.y << endl;
encryptor.AccessKey().SetPublicElement(point);
encryptor.AccessKey().ThrowIfInvalid(prng, 3);
PrintPublicKey(encryptor.GetKey());
string em0; // encrypted message
StringSource ss1(message, true, new PK_EncryptorFilter(prng, encryptor, new StringSink(em0) ) );
cout<<"encrypted msg: "<<em0<<" and its length: "<<em0.length()<<endl;
try
{
// Read key from disk, load it into Crypto++ object
}
catch(const Exception& ex)
{
cerr << "Caught Crypto++ exception " << ex.what() << endl;
}
catch(const std::runtime_error& ex)
{
cerr << "Caught C++ runtime error " << ex.what() << endl;
}
ECIES<ECP>::Decryptor decryptor;
decryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp256r1());
decryptor.AccessKey().SetPrivateExponent(x);
std::string public_point="02C200102C180F9E6A4E7A2F58B5BE86BC179478";
StringSource ss(public_point, true, new HexDecoder);
ECIES<ECP>::Encryptor encryptor;
encryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp128r1());
ECP::Point point;
encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
cout << "X: " << std::hex << point.x << endl;
cout << "Y: " << std::hex << point.y << endl;
encryptor.AccessKey().SetPublicElement(point);
encryptor.AccessKey().ThrowIfInvalid(prng, 3);
string decrypt(std::string encryptedMessage , std::string privateKeyExponent)
{
string decryptedMessage;
try
{
AutoSeededRandomPool prng;
//since the 'privateKeyExponent' is in base-64 format use Base64Decoder
StringSource ss(privateKeyExponent, true /*pumpAll*/, new CryptoPP::Base64Decoder);
Integer x;
x.Decode(ss, ss.MaxRetrievable(), Integer::UNSIGNED);
ECIES<ECP>::Decryptor decryptor;
//curve used is secp256k1
//make decryptor's access key using decoded private exponent's value
decryptor.AccessKey().Initialize(ASN1::secp256k1(), x);
//check whether decryptor's access key is valid or not
bool valid = decryptor.AccessKey().Validate(prng, 3);
if(!valid)
decryptor.AccessKey().ThrowIfInvalid(prng, 3);
cout << "Exponent is valid for P-256k1" << endl;
//decrypt the message using private key
StringSource ss2 (encryptedMessage, true, new PK_DecryptorFilter(prng, decryptor, new StringSink(decryptedMessage) ) );
cout <<"decrypted msg: "<< decryptedMessage<<" and its length: "<<decryptedMessage.length() << endl;
}
catch(const CryptoPP::Exception& ex)
{
std::cerr << ex.what() << endl;
}
return decryptedMessage;
}
string encrypt(std::string message , std::string compressedPublicKeyPoint)
{
string encryptedMessage;
try
{
AutoSeededRandomPool prng;
//public key is a point consisting of "public key point x" and "public key point y"
//compressed public key also known as "public-point" formed using point-compression of public key
//since the key is in base-64 format use Base64Decoder
StringSource ss(compressedPublicKeyPoint, true, new CryptoPP::Base64Decoder);
ECIES<ECP>::Encryptor encryptor;
//curve used is secp256k1
encryptor.AccessKey().AccessGroupParameters()
.Initialize(ASN1::secp256k1());
//get point on the used curve
ECP::Point point;
encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
cout << "X: " << std::hex << point.x << endl;
cout << "Y: " << std::hex << point.y << endl;
//set encryptor's public element
encryptor.AccessKey().SetPublicElement(point);
//check whether the encryptor's access key thus formed is valid or not
encryptor.AccessKey().ThrowIfInvalid(prng, 3);
// encrypted message
StringSource ss1(message, true, new PK_EncryptorFilter(prng, encryptor, new StringSink(encryptedMessage) ) );
cout<<"encrypted msg: "<<encryptedMessage<<" and its length: "<<encryptedMessage.length()<<endl;
}
catch(const CryptoPP::Exception& ex)
{
std::cerr << ex.what() << endl;
}
return encryptedMessage;
}