简体   繁体   English

Java中的椭圆曲线私钥长度

[英]Elliptic Curve Private Key Length in Java

I created a EC key pair using "secp256r1" curve.我使用“secp256r1”曲线创建了一个 EC 密钥对。 It is 256-bit curve and private key should be 256 bits (32 bytes).它是 256 位曲线,私钥应为 256 位(32 字节)。 But what I'm getting is 39 bytes private key.但我得到的是 39 字节的私钥。 Here is my code这是我的代码

 KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); //Provider is SunEC version 1.8
 ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");
 kpg.initialize(ecSpec, new SecureRandom());
 KeyPair ecKeyPair = kpg.generateKeyPair();
 PrivateKey privateKey = ecKeyPair.getPrivate();
 
 ASN1Sequence sequence = DERSequence.getInstance(privateKey.getEncoded());
 DEROctetString subjectPrivateKey =  (DEROctetString) sequence.getObjectAt(2);
 byte[] privateKeyBytes = subjectPrivateKey.getOctets();

 System.out.println("PrivateKeyBytes.length: " + privateKeyBytes.length); // Expected length is 32, but actual is 39 

I'm using JDK 1.8.0_144 and BouncyCastle library.我正在使用 JDK 1.8.0_144 和 BouncyCastle 库。 Here is pom.xml这是 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>pki</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-debug-jdk15on</artifactId>
            <version>1.65</version>
        </dependency>
    </dependencies>
</project> 

How to get 32 bytes of private key?如何获得32字节的私钥?

The algorithm-dependent part of PKCS8, at element #2 of the sequence, for EC is itself a DER encoding, of the SEC1 structure ECPrivateKey, also documented at rfc5915 . PKCS8 的算法相关部分,在序列的元素#2,对于 EC,它本身就是一个 DER 编码,属于SEC1结构 ECPrivateKey,也记录在rfc5915 中 For SunEC this is a SEQUENCE of INTEGER version and OCTETSTRING containing the actual privatekey bytes;对于 SunEC,这是包含实际私钥字节的整数版本和 OCTETSTRING 的序列; the optional context-0 parameters and context-1 publickey are omitted.省略了可选的 context-0 参数和 context-1 公钥。 So you need to parse that:所以你需要解析:

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC",args[0]);
    kpg.initialize(new ECGenParameterSpec("secp256r1"), new SecureRandom());
    KeyPair ecKeyPair = kpg.generateKeyPair();
    PrivateKey privateKey = ecKeyPair.getPrivate();
    byte[] pkcs8 = privateKey.getEncoded();
    
    // slightly reorganized
    DEROctetString wrapped = (DEROctetString) DERSequence.getInstance(pkcs8).getObjectAt(2);
    System.out.println (wrapped.getOctets().length);
    // added
    DEROctetString raw = (DEROctetString) DERSequence.getInstance( wrapped.getOctets() ).getObjectAt(1);
    System.out.println (raw.getOctets().length);

Since you are using BouncyCastle, rather than manually parse the PKCS8 you can use the BouncyCastle class for org.bouncycastle.asn1.pkcs.PrivateKeyInfo :由于您使用的是 BouncyCastle,而不是手动解析 PKCS8,您可以将 BouncyCastle 类用于org.bouncycastle.asn1.pkcs.PrivateKeyInfo

    PrivateKeyInfo info = PrivateKeyInfo.getInstance (DERSequence.getInstance(pkcs8));
    DEROctetString raw2 = (DEROctetString)( DERSequence.getInstance(info.parsePrivateKey()) ).getObjectAt(1);
    System.out.println (raw2.getOctets().length);

and finally, rather than going through the encoding, you can get the privatekey value directly from the ECPrivateKey object as a BigInteger value, which can be converted to a byte array, although it is variable length instead of the fixed length conventionally used for EC privatekeys, so you may need to adjust it:最后,无需经过编码,您可以直接从ECPrivateKey对象中获取私钥值作为BigInteger值,该值可以转换为字节数组,尽管它是可变长度而不是常规用于 EC 私钥的固定长度,所以你可能需要调整它:

    byte[] bytes = ((ECPrivateKey)privateKey).getS().toByteArray();
    System.out.println(bytes.length);
    // may need left-trim or pad with zero(s)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 椭圆曲线密码学 (ECDSA) 私钥匹配公钥 (Java - Bouncy Castle) - Elliptic Curve Cryptography (ECDSA) Private Key Matches Public Key (Java - Bouncy Castle) 使用 java.security.KeyStore 将椭圆曲线证书和私钥导入 Java Keystore - Import elliptic curve Certificate and Private Key into Java Keystore using java.security.KeyStore Java 11 - 椭圆曲线私钥 - java.security.InvalidKeyException:IOException:DER 输入,Integer 标签错误 - Java 11 - elliptic curve private key - java.security.InvalidKeyException: IOException : DER input, Integer tag error 存储/检索椭圆曲线加密 (ECC) 公钥和私钥 - Store/Retrieve Elliptic Curve Cryptography (ECC) public key and private key 使用 BouncyCastle 从文件中读取椭圆曲线私钥 - Reading elliptic curve private key from file with BouncyCastle 将椭圆曲线私钥转换为(未加密的)PKCS#8 格式 - Convert elliptic curve private key to (unencrypted) PKCS#8 format JAVA 11 - 椭圆曲线私钥 - 原因:java.security.InvalidKeyException:IOException:版本不匹配:(支持:00,解析:01 - JAVA 11 - elliptic curve private key - Caused by: java.security.InvalidKeyException: IOException : version mismatch: (supported: 00, parsed: 01 java中的椭圆曲线加密 - Elliptic curve cryptography in java 椭圆曲线ElGamal Java实现 - Elliptic curve ElGamal Java implementation Java 7中的椭圆曲线密码术实现 - Elliptic Curve Cryptography implementation in Java 7
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM