java - 无法使用 Curve25519 生成 DSA/ECDH 密钥以用作使用 Bouncy Castle 的 OpenPGP 密钥
问题描述
我正在尝试使用 Bouncy Castle 的 Java API 使用 DSA 和 ECDH 密钥对组合生成 OpenPGP 密钥环。为了不依赖 NIST 曲线,我选择了 Curve25519 作为我想要使用的函数。但是,在密钥环导出后,我得到一个IllegalArgumentException
:
java.lang.IllegalArgumentException: illegal object in getInstance: org.bouncycastle.asn1.DLSequence at: org.bouncycastle.asn1.ASN1ObjectIdentifier.getInstance(Unknown Source) at: org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter.getPGPPublicKey(Unknown Source) at: org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter.getPGPPublicKey(Unknown Source) at: org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair.getPublicKey(Unknown Source) at: org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair.(Unknown Source)
我用来生成两个密钥对的代码如下:
String identity, passphrase; // User input
OutputStream secretOut, publicOut; // File streams
try {
KeyPairGenerator dsaKeygen = KeyPairGenerator.getInstance ("DSA", "BC");
KeyPairGenerator ecdhKeygen = KeyPairGenerator.getInstance ("ECDH", "BC");
dsaKeygen.initialize (2048);
KeyPair dsaKeypair = dsaKeygen.generateKeyPair ();
X9ECParameters ecParams = CustomNamedCurves.getByName ("Curve25519");
ECParameterSpec ecSpecs = new ECParameterSpec (
ecParams.getCurve (),
ecParams.getG (),
ecParams.getN (),
ecParams.getH (),
ecParams.getSeed ()
);
ecdhKeygen.initialize (ecSpecs, new SecureRandom ());
KeyPair ecdhKeypair = ecdhKeygen.generateKeyPair ();
PGPKeyPair dsaPgpKeypair = new JcaPGPKeyPair (PGPPublicKey.DSA, dsaKeypair, new Date ());
PGPKeyPair ecdhPgpKeypair = new JcaPGPKeyPair (PGPPublicKey.ECDH, ecdhKeypair, new Date ()); // Fails
PGPSignatureSubpacketGenerator flagsGen = new PGPSignatureSubpacketGenerator ();
flagsGen.setKeyFlags (
true,
KeyFlags.CERTIFY_OTHER |
KeyFlags.SIGN_DATA |
KeyFlags.ENCRYPT_COMMS |
KeyFlags.ENCRYPT_STORAGE
);
PGPDigestCalculator sha1Calculator = new JcaPGPDigestCalculatorProviderBuilder ()
.build ()
.get (HashAlgorithmTags.SHA1);
PGPKeyRingGenerator keyRingGenerator = new PGPKeyRingGenerator (
PGPSignature.POSITIVE_CERTIFICATION,
dsaPgpKeypair,
identity,
sha1Calculator,
flagsGenerator.generate (),
null,
new JcaPGPContentSignerBuilder (dsaPgpKeypair.getPublicKey ().getAlgorithm (), AlgorithmTags.SHA1),
new JcePBESecretKeyEncryptorBuilder (PGPEncryptedDate.AES_256, sha1Calculator)
.setProvider ("BC")
.build (passphrase.toCharArray ())
);
keyRingGenerator.addSubKey (ecdhPgpKeypair);
keyRingGenerator.generateSecretKeyRing ().encode (secretOut);
secretOut.close ();
keyRingGenerator.generatePublicKeyRing ().encode (publicOut);
publicOut.close ();
} catch (Exception e) {
// obligatory exception handling
}
供参考:生成 Curve25519 密钥的代码我改编自这个 GitHub 问题,以及生成和导出整个密钥环的代码我改编自这个 Bouncy Castle 示例。
但是,上面的代码使用ECNamedCurveTable
来自prime256v1
.
为什么 JCA 密钥对和 OpenPGP 密钥对之间的转换对于使用 Curve25519 创建的密钥失败,而不是使用来自 的规范创建的密钥ECNamedCurveTable
?我是否遗漏了某些东西,或者 Bouncy Castle 不支持 OpenPGP 键的自定义曲线?
解决方案
推荐阅读
- c# - 如何获取动态 html 元素,而它只有在我们向下滚动到 ***px 时才可见
- python - 使用 apply 将列附加到 DataFrame 并使用行上的 apply 根据现有值计算新列
- javascript - 单击图像时如何从图像中提交图像值
- dart - 在 Flutter 应用程序中标记推送时选择的菜单项
- wordpress - 使用 select2 for wordpress 插件选项页面的多选产品
- java - Spring REST 在双向 JPA 映射时返回递归 JSON
- java - 如何使用存储库和视图模型更新房间数据库中的字段
- angular - 未捕获(承诺):错误:无法匹配任何路由。URL 段:角
- sql - 如何将列值从存储过程中的另一个表更新到表中?
- javascript - 无法调试 AngularJS 项目