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.
// -----------------------------------------------
// 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;
}
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.
--
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.
---
You received this message because you are subscribed to the Google Groups
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.