0

我需要使用 PGP 和 ELGAMAL 算法加密和解密一些消息。我的密钥存储在 JKS 密钥库中。据我了解,我首先需要从 JKS 读取密钥/证书并将它们转换为 PGP 密钥,以便它们可以在 PGP 加密器中使用。

但是,当我尝试使用“JcaPGPKeyConverter”并且如果我为公钥类型提供“PublicKeyAlgorithmTags.ELGAMAL_GENERAL”时,我会得到“org.bouncycastle.openpgp.PGPException:未知 EC 算法”异常。

这是生成 PGP 公钥的转换器代码:

JcaPGPKeyConverter jcaPGPKeyConverter = new JcaPGPKeyConverter();
Certificate encryptionCertificate = keyStore.getCertificate(certificateAlias);
PGPPublicKey pgpEncryptionPublicKey = jcaPGPKeyConverter.getPGPPublicKey(
             PublicKeyAlgorithmTags.ELGAMAL_GENERAL, // if I use ECDH here converter works
             encryptionCertificate.getPublicKey(), new Date());

这是堆栈跟踪:

org.bouncycastle.openpgp.PGPException: unknown EC algorithm
    at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter.getPublicBCPGKey(Unknown Source)
    at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter.getPGPPublicKey(Unknown Source)
    at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter.getPGPPublicKey(Unknown Source)

它适用于“PublicKeyAlgorithmTags.ECDH”(我在 JcaPGPKeyConverter 的源代码中找到),但在后面的步骤中,我从生成的 PGPPublicKey 中获取加密方法。所以如果我在转换器上使用 ECDH 并且只使用写在公钥对象上的算法,我想我不再使用 ELGAMAL 进行加密:

PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256) //
                    .setWithIntegrityPacket(true) //
                    .setSecureRandom(random) //
                    .setProvider(BOUNCY_CASTLE));
// Here I use previously converted public key to generate encryption method and it gets algorithm from public key:
JcePublicKeyKeyEncryptionMethodGenerator encryptionMethodGenerator = 
                                         new JcePublicKeyKeyEncryptionMethodGenerator(pgpEncryptionPublicKey)
                                        .setProvider(BOUNCY_CASTLE);
encryptedDataGenerator.addMethod(encryptionMethodGenerator);

我在 Internet 上看到了 ELGAMAL 的示例,但都可以即时生成密钥。我需要使用保留在 JKS/JCEKS 中的密钥。

是否有另一种方法可以将从 JKS 读取的证书转换为 PGPPublicKey?或者我可以直接在 PGPEncryptedDataGenerator 上定义加密算法(ELGAMAL)吗?

谢谢你的帮助..

4

1 回答 1

0

似乎“jcaPGPKeyConverter.getPGPPublicKey”需要证书的创建日期。在上面的第一个代码块中,我使用执行时间作为带有“new Date()”参数的创建时间。

如果加密和解密发生在同一分钟,例如在单元测试中,这将起作用。否则,由于我们使用不同的时间参数转换密钥,因此在不同时间转换的密钥不能按预期工作。用证书创建时间替换 'new Date()' 参数可以解决问题。

于 2021-07-05T20:58:42.590 回答