生成ecdsa java / scala中的32字节私钥

问题描述 投票:-3回答:1

是否可以使用KeyPairGenerator在java中生成ecdsa 32字节私钥?我的意思是keys.getPublic.getEncoded.length将返回32我试图生成私钥,但大小是144字节

//keys.getPrivate.getEncoded.length - 144 bytes
val ecSpec: ECNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("secp256k1")
val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC")
val secRandom = new SecureRandom()
keyPairGenerator.initialize(ecSpec, secRandom)
val keys = keyPairGenerator.generateKeyPair

//keys.getPrivate.getEncoded.length - 67 bytes
val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance("EC")
keyPairGenerator.initialize(256)
val keys = keyPairGenerator.generateKeyPair
java scala ecdsa
1个回答
1
投票

Java PrivateKey.getEncoded()返回的值是一个编码的私钥,顾名思义。特别是as documented in the superclass Key它是PKCS#8 = Public-Key Cryptography Standard #8, Private Key Information Syntax的ASN.1(DER)编码。 PKCS#8处理用于各种不同公钥算法的私钥,并且除了实际密钥之外还包含元数据,即识别算法和算法的任何参数的'AlgorithmIdentifier';对于ECC算法(ECDSA,ECDH,ECMQV和更多共享一个密钥格式),这些参数指定使用的椭圆曲线组,虽然这个规范有几个选项,但实际上每个人,包括这里的Java,都使用' namedCurve'选项,它通过ASN.1 OID(对象标识符)定义曲线组。

然后,PKCS#8结构包含实际私钥数据,在OCTET STRING中“包装”,格式根据算法而变化。对于ECC,此格式在SEC1 by SECG/Certicom中定义(AFAICT)并包含实际私钥值(数字,表示为OCTET STRING)以及可选的曲线规范和公钥。

您的第一个代码使用BouncyCastle,Bouncy使用包装值生成编码,包括可选的曲线规范和公钥,使其更长。

您的第二个代码默认使用Oracle / Sun提供程序(SunEC),它在没有这些选项的情况下生成编码,但仍包括所需的AlgorithmIdentifier,使其比实际的privatekey值更长。它还使用了不同的曲线:使用整数256初始化SunEC发生器选择secp256r1(又名P-256,prime256v1)NOT secp256k1。如果你改变它以使用new ECGenParameterSpec("secp256k1")作为参数,那么SunEC也将生成secp256k1,但没有选项,给出64字节编码。

在这两种情况下,如果您只想要私钥号,则转换为java.security.interfaces.ECPrivateKey并使用getS()。如果你想把结果放在一个byte / octet数组中,就像传统一样,注意BigInteger.toByteArray()返回一个可变长度的结果,你经常需要保留零修剪或填充它。

如果你确实需要publickey,它有一个类似的方案,使用'X.509'编码,它包含一个AlgorithmIdentifier和一个包装实际的publickey值的BIT STRING,因此比原始的publickey值长。但是在这种情况下,interfaces.ECPublicKeyspec.ECPoint不会为您构建编码;使用Bouncy-only类型可以更方便。

© www.soinside.com 2019 - 2024. All rights reserved.