弹性城堡(Bouncy Castle)PGP解密问题

20

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

异常信息:"error setting asymmetric cipher"。

内部异常信息:"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;
}

密钥没有过期,也没有到期日期:

enter image description here

我没有对应用程序进行任何更改,也没有触及密钥,所以我无法理解为什么问题会突然出现。有什么想法吗?我还可以使用 Kleopatra 手动解密文件,使用相同的密钥在应用程序中加载。

更新1 - 我下载了 .NET 的 OpenPGP Library 免费试用版,它看起来也使用 BouncyCastle,但是我使用相同的密钥解密文件时没有问题。由于某些原因,我使用 BouncyCastle 进行解密的实现已经停止工作了,而我还没有能够确定原因。

更新2 - 我拉出了上周可以用的文件,并下载了 BouncyCastle 的源代码,以便我可以逐步调试并查看异常抛出的位置以及在可用文件和不可用文件之间变量的差异。异常在 PgpPublicKeyEncryptedData 类的 GetDataStream 方法的开头被抛出:

byte[] plain = fetchSymmetricKeyData(privKey);
当我进入这个方法时,对于那些我可以毫无问题地解密的文件,我注意到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);
    }

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

输入图像描述

更新3 - 目前仍未找到解决此问题的方法。昨天我生成了新的密钥(类型为DSA),使用新的密钥后问题已得到解决。

更新4 - 这个问题又出现了,虽然我使用了在上一个更新中起作用的新密钥。再一次,在PgpPublicKeyEncryptedData类中的keyData.Algorithm被看到变成了“RsaGeneral”而不是“ElGamalEncrypt”。为什么算法属性会改变?加密文件的人是否更改了某些内容?


2
证书持有RSA密钥是否已过期?你可以检查一下吗? - Oleksi
我之前已经检查过了,并且刚刚添加了一张截图,我们的密钥没有过期日期。此外,我可以使用类似Kleopatra的工具手动解密文件,使用相同的密钥。所以这些密钥是有效的。 - mservidio
如果您已经解决了问题,应该将解决方案放在答案中并接受它。 - miniBill
1
我真的很希望这可能是关于月球弹跳API的事情。 - MetaGuru
1
大多数情况下,当您遇到偶尔发生的问题时,它并不是加密/解密过程本身的问题。通常与输入/输出不正确有关。在加密的情况下,最常见的问题是将字节视为字符并作为字符传输。问题在于,并非所有字节都编码为字符,导致数据丢失。密码学的有趣之处在于结果应该看起来像随机字符,因此这种问题经常会出现。使用大型、随机生成的数据集进行测试,以避免此类问题。 - Maarten Bodewes
2个回答

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);
            }
        }

0

看起来另一个方面正在使用其他/不同的密钥进行加密。 可能您的密钥环中也包含RSA密钥,但BouncyCastle仅使用第一个(???)。 使用gpg,您可以通过发出“gpg --list-packets YourEncryptedFile.pgp”命令来检查加密文件的内容。

之后将相同的命令应用于“好”的文件和您的密钥环,并比较密钥标识符与哪个文件被加密。 由于您正在使用DSA密钥,因此文件应加密为ElGamal子密钥。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接