【问题标题】:Create PrivateKey from byte array从字节数组创建 PrivateKey
【发布时间】:2011-01-05 01:31:42
【问题描述】:

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

谢谢, 武克

【问题讨论】:

标签: java cryptography javacard


【解决方案1】:

我也在寻找这个答案,终于找到了。 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 做过任何事情,但从这个 post 看来,您可以使用 KeyFactory 类。您可能需要下载 BouncyCastle 库。

【讨论】:

  • 谢谢。做得好!你为我节省了数小时的研究时间。这应该被选为正确答案,除非 OP 的平台不支持充气城堡。
  • 我不明白你所说的“如果你愿意”是什么意思。是可选的吗?
  • @Jus12 我的意思是如果你想使用 BouncyCastle 并且它还没有包含在你正在使用的平台上作为提供程序。例如,在 Android 上,我添加了 BouncyCastle 库,并且必须使用该行将 BC 添加为提供程序并使用 BC 的算法实现。很高兴我能帮助别人! :)
【解决方案2】:

如Java docs中所述

密钥通常通过密钥生成器、证书或用于管理密钥的各种身份类获得。也可以通过使用密钥工厂从密钥规范(底层密钥材料的透明表示)中获取密钥。

KeyFactory 类可以帮助您解决这个问题。

【讨论】:

  • 我忘了说我正在使用不支持 KeyFactory 类的 javacard。它确实支持 keyBuilder,但我无法真正弄清楚如何使用这个类来满足我的需要。
【解决方案3】:

丢弃编码的字节数组。在 JavaCard 上,AFAIR 无法直接对其进行解码 - 您必须分别设置不同的关键组件。

例如,一个 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。
  • getEncoded() 仅在 J2SE 上可用。它返回一个 PKCS#8 编码形式的私钥,几乎可以在任何地方使用。 JavaCard 平台就是这些例外之一。
  • @罗伯特我明白了。感谢您的澄清。
  • @Robert 我在卡上生成了一个密钥对,我想在响应 APDU 中发送公钥。如何从公钥生成字节数组?谢谢!
【解决方案4】:
//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);

【讨论】:

    【解决方案5】:

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

    【讨论】:

      猜你喜欢
      • 2011-10-05
      • 2015-11-19
      • 2013-09-23
      • 2012-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      相关资源
      最近更新 更多