从字节数组创建私钥

9
有没有一种方法可以从字节数组生成PrivateKey?我使用getEncoded()方法得到了这个字节数组,但现在我必须将它转换回PrivateKey。
谢谢, Vuk

不,这并没有帮助到我,但还是谢谢您。 - Vuk
5个回答

8
我也在寻找这个答案,最终找到了。keyBytes是一个字节数组,最初是由getEncoded()创建的。
//add BouncyCastle as a provider if you want
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
//create a keyfactory - use whichever algorithm and provider
KeyFactory kf = KeyFactory.getInstance("DSA", "BC");
//for private keys use PKCS8EncodedKeySpec; for public keys use X509EncodedKeySpec
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey pk = kf.generatePrivate(ks);

我从这篇帖子中了解到,虽然我没有为JavaCard做过任何事情,但似乎可以使用KeyFactory类。您可能需要下载BouncyCastle库。


1
谢谢。做得很好!你为我节省了几小时的研究时间。这应该被选为正确的答案,除非OP的平台不支持bouncy castle。 - Jus12
我不明白你所说的“if you want”的意思。这是可选的吗? - Jus12
@Jus12 我的意思是,如果你想使用BouncyCastle,但它并没有作为提供者包含在你所使用的平台上。例如,在Android上,我添加了BouncyCastle库,并使用了那行代码将BC添加为提供者,并使用BC的算法实现。很高兴能帮助到某个人! :) - marchica

5
根据Java文档所述:
通过密钥生成器、证书或各种用于管理密钥的身份验证类通常可以获取密钥。也可以通过使用密钥工厂从密钥规范(底层密钥材料的透明表示)中获取密钥。 KeyFactory类可以帮助您完成这项任务。

我忘了说我正在使用JavaCard,它不支持KeyFactory类。它确实支持keyBuilder,但是我真的弄不清楚如何将这个类用于我的需求。 - Vuk

3

丢弃编码的字节数组。在JavaCard上,我记得没有直接解码它的方法 - 您必须分别设置不同的密钥组件。

例如,RSAPrivateKey需要使用指数和模数进行初始化:

rsaPrivate = (RSAPrivateKey) javacard.security.KeyBuilder.buildKey
  (javacard.security.KeyBuilder.TYPE_RSA_PRIVATE, 
  javacard.security.KeyBuilder.LENGTH_RSA_512, false);

byte[] exponent = {(byte) 7};
byte[] modulus = {(byte) 33};
rsaPrivate.setExponent(exponent, (short) 0, (short) exponent.length);
rsaPrivate.setModulus(modulus, (short) 0, (short) modulus.length);

顺便说一句:如果您有JavaCard相关的问题,我建议你在Oracle论坛上的JavaCard Forum上寻求帮助。如果您在那里搜索RSAPrivateKey,您会发现一些有趣的帖子。


getEncoded的意义是什么?他们可能会抛出UnsupportedOperationException。 - Jus12
getEncoded()仅适用于J2SE。它以PKCS#8编码形式返回私钥,几乎可以在任何地方使用。JavaCard平台是其中之一的例外。 - Robert
@Robert,我在卡上生成了一对密钥,并希望在响应APDU中发送公钥。我该如何从公钥生成一个字节数组?谢谢! - bp14

1
//ECDSA algo of signature type prime256 of key
Security.addProvider(new BouncyCastleProvider());
KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(new BigInteger(1, privKey), spec);
PrivateKey privateKey = factory.generatePrivate(ecPrivateKeySpec);

0

你可以自己解码 PKCS#8 编码的 blob(ASN.1 BER 解析)并设置组件,或者从私钥中获取组件(至少是私有指数和模数)作为 Java BigIntegers,将它们转换为无符号字节数组,并按照 Robert 的说明在 Java Card API 中设置它们。PKCS#8 解析可以在 Java Card 上完成,但这是一个相当可怕的练习。


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