// -----------------------------------------------
// Save Buffered Transformation to File
void Crypto::RSAKey::Save(const string& filename, CryptoPP::BufferedTransformation& bt){
FileSink file(filename.c_str());
bt.CopyTo(file);
file.MessageEnd();
}
// -----------------------------------------------
// Load Buffered Transformation from file
void Crypto::RSAKey::Load(const string& filename, BufferedTransformation& bt){
CryptoPP::FileSource file(filename.c_str(), true);
file.TransferTo(bt);
bt.MessageEnd();
}
// -----------------------------------------------
// Save Public Key to File
RC Crypto::RSAKey::SavePublicKey(const string& fp, RSA::PublicKey& key){
try {
CryptoPP::ByteQueue queue;
key.Save(queue);
Save(fp, queue);
} catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Failed to Save Public Key to File(" << fp << "): " << e.what() << std::endl;
return RC::ERR_CRYPTOPP;
}
return RC::SUCCESS;
}
// -----------------------------------------------
// Save Private Key to File
RC Crypto::RSAKey::SavePrivateKey(const string& fp, RSA::PrivateKey& key){
try {
CryptoPP::ByteQueue queue;
key.Save(queue);
Save(fp, queue);
} catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Failed to Save Private Key to File(" << fp << "): " << e.what() << std::endl;
return RC::ERR_CRYPTOPP;
}
return RC::SUCCESS;
}
// -----------------------------------------------
// Load Public Key from file
RC Crypto::RSAKey::LoadPublicKey(const string& fp, RSA::PublicKey& key, bool validate){
AutoSeededRandomPool rnd;
try {
CryptoPP::ByteQueue queue;
Load(fp, queue);
key.Load(queue);
if(validate)
key.Validate(rnd, 3);
} catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Failed to Load Public Key from File(" << fp << "): " << e.what() << std::endl;
return RC::ERR_CRYPTOPP;
}
return RC::SUCCESS;
}
// -----------------------------------------------
// Load Private Key from File
RC Crypto::RSAKey::LoadPrivateKey(const string& fp, RSA::PrivateKey& key, bool validate){
AutoSeededRandomPool rnd;
try {
CryptoPP::ByteQueue queue;
Load(fp, queue);
key.Load(queue);
if(validate)
key.Validate(rnd, 3);
} catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Failed to Load Private Key from File(" << fp << "): " << e.what() << std::endl;
return RC::ERR_CRYPTOPP;
}
return RC::SUCCESS;
}
// -----------------------------------------------
// Generate Public+Private Keys and save to file
RC Crypto::RSAKey::generateKeysAndSave(const string &prifp, const string &pubfp){
AutoSeededRandomPool rnd;
RSA::PrivateKey pri;
RC r;
pri.GenerateRandomWithKeySize(rnd, KEYSIZE);
RSA::PublicKey pub(pri);
r = SavePrivateKey(prifp, pri);
if(r != RC::SUCCESS){
return r;
}
r = SavePublicKey(pubfp, pub);
if(r != RC::SUCCESS){
return r;
}
return RC::SUCCESS;
}
// -----------------------------------------------
// Sign Message
RC Crypto::RSAEncryptor::sign(){
try {
AutoSeededRandomPool rng;
StringSource(msg, true, new SignerFilter(rng, *snr, new StringSink(sig), false));
}
catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Unable to sign message. " << e.what() << " - error type("<<e.GetErrorType()<<")" << std::endl;
return RC::ERR_CRYPTOPP;
}
return RC::SUCCESS;
}
// -----------------------------------------------
// Encrypt message
RC Crypto::RSAEncryptor::encrypt(){
RC r = RC::SUCCESS;
try {
// Sign
if ((r = sign()) != RC::SUCCESS)
return r;
cout << "PRE ENCRYPT" <<endl;
// Encrypt
AutoSeededRandomPool rng;
StringSource ss(msg, true, new PK_EncryptorFilter(rng, *enc, new StringSink(cphr)));
// Convert to Hex format
if(hex_out){
string c = "";
StringSource ss2(cphr, true, new CryptoPP::HexEncoder(new StringSink(c)));
cphr = c;
}
} catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Unable to encrypt message. " << e.what()<< " - error type("<<e.GetErrorType()<<")" << std::endl;
return RC::ERR_CRYPTOPP;
}
return r;
}
// -----------------------------------------------
// Decrypt
RC Crypto::RSADecryptor::decrypt(){
RC r = RC::SUCCESS;
try {
// Convert cphr from hex to octal
if(hex_in){
CryptoPP::HexDecoder decoder;
string dec;
decoder.Attach(new StringSink(dec));
decoder.Put((byte*)cphr.data(), cphr.size());
decoder.MessageEnd();
cphr = dec;
}
// Decrypt
AutoSeededRandomPool rng;
StringSource ss(cphr, true, new PK_DecryptorFilter(rng, *dec, new StringSink(msg)));
// Verify
if ((r = verify()) != RC::SUCCESS)
return r;
} catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Unable to decrypt message." << std::endl;
return RC::ERR_CRYPTOPP;
}
return r;
}
// -----------------------------------------------
// Verify
RC Crypto::RSADecryptor::verify(){
try {
StringSource ss(msg+sig, true, new SignatureVerificationFilter(*ver, NULL, SignatureVerificationFilter::THROW_EXCEPTION));
} catch (CryptoPP::Exception e) {
LOG(ERROR) << "Error: Unable to verify message."<< std::endl;
return RC::ERR_CRYPTOPP;
}
return RC::SUCCESS;
}
...
LOG(ERROR) << "Error: Failed to Load Public Key from File(" << fp <span style="color: #660;" class="style
LOG(ERROR) << "Error: Failed to Load Public Key from File(" << fp <span style="color: #660;" class="style
...
I have been using crypto++'s RSA cryptographic methods for a project. Encryption, decryption, signing and verifying all worked well until about two days ago, when I updated xcode and its libraries. Since then signing and verification has completely stopped working returning the error: PK_Signer: key too short for this signature scheme. I am using the recommended 3072 byte key size and all my methods are essentially copies of the RSA examples.
...
Encryption and Decryption works fine with the generated keys, but signing and verification are both problematic. As the code was working fine before, I am at a loss as to what is wrong... Anyone got any ideas.