Search code examples
c++cryptographycrypto++

Importing a private key from a string using Crypto++


So first I create a signing object like so:

CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer signer;

I generate them like so:

CryptoPP::AutoSeededRandomPool prng; //Create a random number
signer.AccessKey().Initialize(prng, CryptoPP::ASN1::secp256r1());

I also validate the generated keys to check everything is fine:

signer.AccessKey().Validate(prng, 3))

These are then exported to a string:

std::string key;
CryptoPP::StringSink pss(key);
signer.AccessKey().Save(pss);

However when it comes to loading these keys back up:

CryptoPP::StringSink ss(key);
signer.AccessKey().Load(ss);

I receive and exception:

BER decode error

Just to note the signing object is blank upon attempting to load could this be it?

I'm not sure what I'm doing wrong I believe it's the method for loading the key back into the Access key and I should be importing the key to the StringSink differently but I'm not sure. Please could I have some help trying to load my keys.


Solution

  • This is correct:

    std::string p_key;
    CryptoPP::StringSink pss(p_key);
    signer.AccessKey().Save(pss);
    

    This looks like the problem assuming p_key and key are the same:

    CryptoPP::StringSink ss(key);
    signer.AccessKey().Load(ss);
    

    Use as StringSource when loading, not a StringSink:

    CryptoPP::StringSource ss(key);
    signer.AccessKey().Load(ss);
    

    All sources and sinks are interchangeable. You can use a FileSource instead of a StringSource; and a FileSink instead of a StringSink. But you can't replace a source with a sink (or vice versa).

    StringSource and StringSink are part of pipelines in Crypto++. Pipelines and Keys and Formats from the Crypto++ wiki may be useful for you. But the code you showed is clean (other than the typo) so you may not need them.