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

在java/scala中生成ecdsa 32字节私钥,java,scala,ecdsa,Java,Scala,Ecdsa,是否可以使用KeyPairGenerator在java中生成ecdsa 32字节私钥?我的意思是keys.getPublic.getEncoded.length将返回32 我试图生成私钥,但大小是144字节 //keys.getPrivate.getEncoded.length - 144 bytes val ecSpec: ECNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("secp256k1") val keyPai

是否可以使用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 PrivateKey.getEncoded返回的值是一个编码的PrivateKey,正如名称所示。具体来说,它是的ASN.1 DER编码。PKCS8处理各种不同公钥算法的私钥,除实际密钥外还包含元数据,即识别算法和算法任何参数的“算法标识符”;对于ECC算法ECDSA、ECDH、ECMQV和更多共享一个密钥格式,这些参数指定了所使用的椭圆曲线组,尽管此规范有多个选项,但实际上每个人,包括这里的Java,都使用“namedCurve”选项,该选项通过ASN.1 OID aka对象标识符定义曲线组

然后,PKCS8结构包含实际的私钥数据,“包装”在八位字节字符串中,格式根据算法的不同而不同。对于ECC,此格式在中定义为AICT,并包含实际私钥值和一个数字,表示为八位字节字符串加上curve spec(可选)和公钥

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

默认情况下,您的第二个代码使用Oracle/Sun提供程序SunEC,该提供程序在不使用这些选项的情况下生成编码,但仍然包含所需的算法标识符,使其比实际的privatekey值长。它还使用了一条不同的曲线:使用整数256初始化SunEC生成器时选择secp256r1,也称为P-256,prime256v1而不是secp256k1。如果将此更改为使用新ECGENP256K1作为参数,则SunEC也将生成secp256k1,但不包含选项,提供64字节编码

在这两种情况下,如果只需要privatekey号码,请强制转换为并使用getS。如果您希望结果以字节/八位字节数组的形式出现,请注意biginger.toByteArray返回一个可变长度的结果,您通常需要对其进行左零修剪或填充


如果您确实想要公钥,它有一个使用“X.509”编码的类似方案,该编码包含算法标识符和一个包含实际公钥值的位字符串,因此比原始公钥值长。但是在这种情况下interfaces.ECPublicKey和spec.ECPoint不会为您构建编码;使用Bouncy only类型更方便。

欢迎使用stackoverflow。请访问该网站,了解stackoverflow是如何工作的,以及如何提出好的问题。然后回来问你的问题。包括您尝试的代码,以及任何错误消息。提出具体问题。大多数人都乐意帮忙,但不想为你做工作。像我怎么做x这样的问题?这并没有表明你在这方面的任何研究工作都可能被忽视。你的意思是.getPrivate而不是.getPublic;未压缩点的secp256k1原始公钥是65字节而不是32字节。