问题
I've had a application using Bouncy Castle for PGP decryption which has run without any issues for the past 8 months or so, and the past 2 days all of a sudden an issue has come up where the GetDataStream method is throwing an exception:
Exception Message: "error setting asymmetric cipher".
Inner Exception Message : "Not an RSA key".
private static PgpObjectFactory getClearDataStream(PgpPrivateKey privateKey, PgpPublicKeyEncryptedData publicKeyED)
{
// Exception throws here.
Stream clearStream = publicKeyED.GetDataStream(privateKey);
PgpObjectFactory clearFactory = new PgpObjectFactory(clearStream);
return clearFactory;
}
The key hasn't expired, it has no expiration date:
I haven't made any changes to the application, I haven't touched the keys, so I can't quite understand why an issue has come up out of the blue. Any ideas? I can also manually decrypt the files using Kleopatra using the same keys that I load in the application.
Update 1 - I downloaded the free trial for OpenPGP Library for .NET, which looks to use BouncyCastle also, and I have no issues decrypting the files using the same key. For some reason, my implementation of decryption using BouncyCastle that has worked for several months stopped working for some reason that I have not been able to identify yet.
Update 2 - I pulled files from last week that worked, and I've also downloaded the source code of BouncyCastle in order that I can step through and debug to see where the exception is throwing and how the variables differ between a file that works and a file that doesn't work. The exception is being thrown at the beginning of the GetDataStream method of the PgpPublicKeyEncryptedData class:
byte[] plain = fetchSymmetricKeyData(privKey);
When I step into this method, for files that I can decrypt without any problem, I've noticed that the keyData.Algorithm variable is set to "ElGamalEncrypt", whereas for files that the exception throws, the file keyData.Algortithm is set to "RsaGeneral". Why would these differ? Did the company sending me the files change their encryption method? And is this encryption method not properly supported by BouncyCastle?
private byte[] fetchSymmetricKeyData(PgpPrivateKey privKey)
{
IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm);
try
{
c1.Init(false, privKey.Key);
}
catch (InvalidKeyException e)
{
throw new PgpException("error setting asymmetric cipher", e);
}
Also, not sure if this is related, the certificate type of our key is DSA.
Update 3 - I've been unable to figure out how to resolve the issue as of yet given the current keys. I generated new keys (type DSA) yesterday, and with the new keys the issue has been resolved.
Update 4 - This issue has just come up again, with the new key that worked in my last update. Once again, the keyData.Algorithm within the PgpPublicKeyEncryptedData class is being see to "RsaGeneral" instead of "ElGamalEncrypt" now. Why would the Algorithm property change? Is the person encrypting the file changing something?
回答1:
This could be important (Source: http://www.opensourcejavaphp.net/csharp/itextsharp/PgpPublicKeyEncryptedData.cs.html) :
It explains the value of your keyData.Algorithm being different, but the why I am still unsure of. It is most likely the input file that is the case. It could be different (client using a different key?)
private static IBufferedCipher GetKeyCipher(
PublicKeyAlgorithmTag algorithm)
{
try
{
switch (algorithm)
{
case PublicKeyAlgorithmTag.RsaEncrypt:
case PublicKeyAlgorithmTag.RsaGeneral:
return CipherUtilities.GetCipher("RSA//PKCS1Padding");
case PublicKeyAlgorithmTag.ElGamalEncrypt:
case PublicKeyAlgorithmTag.ElGamalGeneral:
return CipherUtilities.GetCipher("ElGamal/ECB/PKCS1Padding");
default:
throw new PgpException("unknown asymmetric algorithm: " + algorithm);
}
}
catch (PgpException e)
{
throw e;
}
catch (Exception e)
{
throw new PgpException("Exception creating cipher", e);
}
}
回答2:
Looks like another party is encrypting to other/different keys. Probably your keyring contains RSA key as well, but BouncyCastle uses only the first (???). Using gpg, you can check the contents of your encrypted file by issuing gpg --list-packets YourEncryptedFile.pgp
After that apply the same command to 'good' file, and to your keyrings, and compare key identifiers to which file is encrypted. Since you are using DSA keys, file should be encrypted to ElGamal subkey.
来源:https://stackoverflow.com/questions/11106918/bouncy-castle-pgp-decryption-issue