Bouncy Castle PGP解密问题

mse*_*dio 19 c# encryption bouncycastle pgp encryption-asymmetric

我有一个使用Bouncy Castle进行PGP解密的应用程序,在过去的8个月左右没有任何问题,过去2天突然出现了GetDataStream方法引发异常的问题:

异常消息:"错误设置非对称密码".

内部异常消息:"不是RSA密钥".

private static PgpObjectFactory getClearDataStream(PgpPrivateKey privateKey, PgpPublicKeyEncryptedData publicKeyED)
{
    // Exception throws here.
    Stream clearStream = publicKeyED.GetDataStream(privateKey);

    PgpObjectFactory clearFactory = new PgpObjectFactory(clearStream);
    return clearFactory;
}
Run Code Online (Sandbox Code Playgroud)

密钥尚未过期,没有到期日期:

在此输入图像描述

我没有对应用程序进行任何更改,我没有触及按键,所以我不太明白为什么一个问题突然出现了.有任何想法吗?我也可以使用我在应用程序中加载的相同密钥使用Kleopatra手动解密文件.

更新1 - 我下载了OpenPGP Library for .NET的免费试用版,它也希望使用BouncyCastle,我也没有问题使用相同的密钥解密文件.出于某种原因,我使用已经工作了几个月的BouncyCastle实现的解密由于某种原因而停止工作,我还无法识别.

更新2 - 我上周提取的文件有效,我还下载了BouncyCastle的源代码,以便我可以单步调试以查看异常抛出的位置以及变量在工作和一个不起作用的文件.在PgpPublicKeyEncryptedData类的GetDataStream方法的开头抛出异常:

byte[] plain = fetchSymmetricKeyData(privKey);
Run Code Online (Sandbox Code Playgroud)

当我进入这个方法时,对于我可以解密而没有任何问题的文件,我注意到keyData.Algorithm变量设置为"ElGamalEncrypt",而对于异常抛出的文件,文件keyData.Algortithm设置为"RsaGeneral".为什么这些不同?公司向我发送文件是否更改了加密方法?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);
    }
Run Code Online (Sandbox Code Playgroud)

此外,不确定这是否相关,我们的密钥的证书类型是DSA.

在此输入图像描述

更新3 - 在给定当前密钥的情况下,我一直无法弄清楚如何解决问题.我昨天生成了新密钥(类型为DSA),并且使用新密钥解决了问题.

更新4 - 这个问题刚刚出现,我的上一次更新中使用了新密钥.现在,PgpPublicKeyEncryptedData类中的keyData.Algorithm再次被看作"RsaGeneral"而不是"ElGamalEncrypt".为什么Algorithm属性会改变?加密文件的人是在改变什么吗?

Iss*_*ram 1

这可能很重要(来源:http://www.opensourcejavaphp.net/csharp/itextsharp/PgpPublicKeyEncryptedData.cs.html):

它解释了您的 keyData.Algorithm 的值不同,但我仍然不确定为什么。输入文件很可能就是这种情况。它可能会有所不同(客户端使用不同的密钥?)

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);
            }
        }
Run Code Online (Sandbox Code Playgroud)