C++ 在ECIE中使用以前生成的私钥

C++ 在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

我想使用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.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;
}