I thought PEM format "consists of the DER format base64 encoded with additional header and footer lines.", Openssl manual (http://www.openssl.org/docs/apps/rsa.html), so I thought that if I just got rid of the header and footer lines I'd have a DER Base64 encoded file that I could feed into the Crypto++ routines as the keys.
When I try this and try encoding data, using the public key, it appears to produce an encoded message, ie it all completes successfully. But when I try and decode the message, private key, I get a "BER decode error" exception.
The routines I have work fine so long as the keys are generated with the crypto++ functions.
If anyone out there can offer advice or point me in the right direction it would be much appreciated.
The openssl command lines I'm using are:
openssl genrsa -out privkey.asc 2048
openssl rsa -in privkey.asc -pubout -out pubkey.ascI seperated my code into 3 programs to help with debugging. The crypto programs that comprise my tests are (stolen right out of the test program :-):
Key generation: ---------------
void GenerateRSAKey(unsigned int keyLength,
const char *privFilename,
const char *pubFilename,
const char *seed)
{
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed)); RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
Base64Encoder privFile(new FileSink(privFilename));
priv.DEREncode(privFile);
privFile.MessageEnd(); RSAES_OAEP_SHA_Encryptor pub(priv);
Base64Encoder pubFile(new FileSink(pubFilename));
pub.DEREncode(pubFile);
pubFile.MessageEnd();
}int main(int argc, char** argv)
{
GenerateRSAKey( 2048, "privkey.asc", "pubkey.asc", "A random string or 345%");
}
Encrypt the message:
--------------------
string RSAEncryptString(const char *pubFilename,
const char *seed,
const char *message)
{
FileSource pubFile(pubFilename, true, new Base64Decoder);
RSAES_OAEP_SHA_Encryptor pub(pubFile); RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));string result;
StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
Base64Encoder(new StringSink(result))));
return result;
}
int main(int argc, char** argv)
{
string encStr;
FILE *op;try {
encStr = RSAEncryptString("pubkey.asc", "dribbleSeed23", "A few good men, 175 to be exact\n");
op = fopen("rsaMsg.txt", "w");
fprintf(op, "%s\n", encStr.c_str());
fclose(op);
}
catch (std::exception const& e)
{
// This clause will also catch CryptoPP::Exception as well as
// all derived exception classes
cout << "std::exception caught:" << endl
<< e.what() << endl;
} }
Decrypt the message: -------------------- string RSADecryptString(const char *privFilename, const char *ciphertext) { FileSource privFile(privFilename, true, new Base64Decoder); RSAES_OAEP_SHA_Decryptor priv(privFile); RandomPool randomPool;
string result;
StringSource(ciphertext,
true,
StringSink(result))));
new HexDecoder(new PK_DecryptorFilter(randomPool, priv, new StringSink(result))));
return result;
}
int main(int argc, char** argv)
{
string decrStr;
FILE *ip;
char ipStr[3000]; ip = fopen("rsaMsg.txt", "r");
fgets(ipStr, 3000, ip); // get rid of the \n at the end of the line
ipStr[strlen(ipStr) - 1] = '\0'; try {
decrStr = RSADecryptString("privkey.asc", ipStr);
printf("%s\n", decrStr.c_str()); fclose(ip);
}
catch (std::exception const& e)
{
// This clause will also catch CryptoPP::Exception as well as
// all derived exception classes, except for SpecificException
// which has already been caught above.
cout << "std::exception caught:" << endl
<< e.what() << endl;}
}
