I have a problem with rconstructing the private key from byte array in Kotlin (using Android Studio)
I must load the private key that I have defined like below. From what I know, this EC Private key is 32 bytes long which correspond to secp256r1 curve
0x3C, 0x6D, etc... (this have 32 in total)
This is what i have:
val privateKeyArray = arrayOf(0x3C, 0x6D, etc...) //this have 32 size
Then I am trying to convert it to byteArray:
val privateKeyBytes = privateKeyArray.map { it.toByte() }.toByteArray())
And then I want to sign some data with it:
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()
However, when i am trying to generate the privateKey from the keyFactory I am getting the following Exception:
java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0c000079:ASN.1 encoding routines:OPENSSL_internal:HEADER_TOO_LONG at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
How can I properly read the private key in this case?
I used BouncyCastle as the security provider, so you can try it as well.
looks like the spec you are using is secp256r1
. in this case, try following code to regen the PrivateKey object from the byte array that represents the key. remember, the byte array is just a BigInteger in Java.
let me know if it works or not.
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);
}