I wan to encrypt /decrypt data using ECIES , I am using cryptopp for this.
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) ) );
Everything else is fine but I want to do the above same thing using already generated 'private key' and not randomly generated 'private key' unlike the case above. How can I do this?
I have tried the following code but it just simply crashes
AutoSeededRandomPool prng;
std::string privatekeyString="02C200102C180F9E6A4E7A2F58B5BE86BC179478";
CryptoPP::HexDecoder decoder;
decoder.Put((byte*)privatekeyString.data(), privatekeyString.size());
decoder.MessageEnd();
ECIES<ECP> ::Decryptor d0;
d0.AccessKey().AccessGroupParameters().Initialize(ASN1::secp128r1());
crash point
//load private key
d0.AccessKey().Load(decoder);
PrintPrivateKey(d0.GetKey());
//get public key
ECIES<ECP>::Encryptor e0(d0);
PrintPublicKey(e0.GetKey());
string em0; // encrypted message
StringSource ss1(message, true, new PK_EncryptorFilter(prng, e0, 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, d0, new StringSink(dm0) ) );
cout <<"decrypted msg: "<< dm0<<" and its length: "<<dm0.length() << endl;
Edit 2
In response to @jww answer I managed to decode the message with the private key as:
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;
}
But when I try to encrypt the message using public key I got error
CryptoPP::CryptoMaterial::InvalidMaterial: CryptoMaterial: this object contains invalid values
Here is my code:
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;
The problem I am having is you don't appear to know what you have, and the some of the parameters you are using are wrong when taken with the other parameters. So its pretty much a stab in the dark.
First, you should wrap the disk operations in a
try/catch
. I/O can always cause problems, so be sure to catch exceptions related to theiostream
stuff. You should also catch the Crypto++ Exception related to key loading. That will handle the "crash" with no information.So your code might look something like:
Second, this looks like a private exponent, and not a private key:
And its too big to be in
P-128
. Maybe you should do something like:Or, you can:
If you add the following to the program above:
You will get the following for the private key:
As you can see, the key is not
"02C200102C180F9E6A4E7A2F58B5BE86BC179478"
.The 12 leading 0's look suspicious to me. Though the exponent validates, you should verify the exponent and the field. The closest fit I could find is the curve
secp160r2
(of course, curves likesecp192k1
andsecp224k1
work too).The private key above is the hex encoding of
ecies.priv.der
shown below.Third, this could be a public point in compressed form due to the leading
02
.If that is the case, then you are supposed to be able to do this, but I can't get it to decode the point (see Minimizing Key Size for Persistence on the wiki).
x
andy
are 0 after the operation; maybe the problem is with the field:Fourth, you should probably save the entire key, and not just the exponent. Here's a program for you that shows you how to save and load the keys. It also shows you how to perform encryption and decryption in one-liners.
Here is what a private key looks like from the test program above. Notice it has the field encoded into the structure so you don't have to guess at it (
P-256
versusP-128
versusP-521
).And the public key:
Crypto++ has a wiki page on ECIES. See Elliptic Curve Integrated Encryption Scheme. They also have Bouncy Castle interop workarounds.
You can also PEM encode the keys, but you need a patch to do it because its not part of the library. For the patch, see PEM Pack on the Crypto++ wiki.
As jww suggested I have successfully completed encryption and decryption. Below are the code snippets if anyone wants.
Decryption
Encryption
I'm going to add another answer to show you how to serialize private exponents and public points in case you had trouble with the public points. It also shows you how to
Save
the PrivateKeyInfo and SubjectPublicKeyInfo.Its produces output similar to below. You will need a patch for the
Base64URLEncoder
. its not part of the library.With the private exponent and public point above, the following works just fine: