我在Kotlin(使用Android Studio)中从字节数组r构造私钥时遇到问题
我必须加载已定义的私钥,如下所示。
据我所知,此EC私钥的长度为32个字节,对应于secp256r1曲线
0x3C, 0x6D, etc... (this have 32 in total)
这就是我所拥有的:
val privateKeyArray = arrayOf(0x3C, 0x6D, etc...) //this have 32 size
然后我试图将其转换为byteArray:
val privateKeyBytes = privateKeyArray.map { it.toByte() }.toByteArray())
然后我要用它签名一些数据:
val keyFactory = KeyFactory.getInstance("EC")
val privateKey = keyFactory.generatePrivate(PKCS8EncodedKeySpec(privateKeyBytes)) //THIS line gives the Exception
val content = "random string".toByteArray()
val signer = Signature.getInstance("SHA256withECDSA")
signer.initSign(privateKey)
signer.update(content)
val signature = signer.sign()
但是,当我尝试从keyFactory生成privateKey时,出现以下异常:
在这种情况下,如何正确读取私钥?
最佳答案
我使用BouncyCaSTLe作为安全提供程序,因此您也可以尝试使用它。
看起来您正在使用的规范是secp256r1
。在这种情况下,请尝试以下代码从代表密钥的字节数组中重新生成PrivateKey对象。记住,字节数组只是Java中的BigInteger。
让我知道它是否有效。
public PrivateKey generatePrivateKey(byte[] keyBin) throws InvalidKeySpecException, NoSuchAlgorithmException {
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256r1");
KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
ECNamedCurveSpec params = new ECNamedCurveSpec("secp256r1", spec.getCurve(), spec.getG(), spec.getN());
ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(new BigInteger(keyBin), params);
return kf.generatePrivate(privKeySpec);
}