有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从十六进制字符串创建EC私钥

我想知道这是否是从这个网站的十六进制字符串在Java中创建PrivateKey对象的正确方法:https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html

从十六进制字符串创建BigInteger:

BigInteger priv = new BigInteger(privateKeyFromSite, 16);

并传递给此方法:

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;

import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;


public static PrivateKey getPrivateKeyFromECBigIntAndCurve(BigInteger s, String curveName) {

    ECParameterSpec ecParameterSpec = ECNamedCurveTable.getParameterSpec(curveName);

    ECPrivateKeySpec privateKeySpec = new ECPrivateKeySpec(s, ecParameterSpec);
    try {
        KeyFactory keyFactory = KeyFactory.getInstance(EC);
        return keyFactory.generatePrivate(privateKeySpec);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
        return null;
    }
}

共 (1) 个答案

  1. # 1 楼答案

    是的,这是正确的,EC私钥只是一个数字。如果打印出PrivateKey,您将看到相应公钥的X和Y坐标

    例如,假设生成了以下密钥对(secp256r1):

    • EC私钥:
      1b9cdf53588f99cea61c6482c4549b0316bafde19f76851940d71babaec5e569

    • EC公钥:
      0458ff2cd70c9a0897eb90a7c43d6a656bd76bb8089d52c259db6d9a45bfb37eb9882521c3b1e20a8bae181233b939174ee95e12a47bf62f41a62f1a20381a6f03

    我们将私钥字节插入您的函数:

    BigInteger priv = new BigInteger("1b9cdf53588f99cea61c6482c4549b0316bafde19f76851940d71babaec5e569", 16);
    PrivateKey privateKey = getPrivateKeyFromECBigIntAndCurve(priv, "secp256r1");
    System.out.println(privateKey);
    

    然后打印出来:

    EC Private Key [91:05:8a:28:94:f9:5c:cb:c4:34:b8:69:e4:39:d4:57:59:c7:51:35]
            X: 58ff2cd70c9a0897eb90a7c43d6a656bd76bb8089d52c259db6d9a45bfb37eb9
            Y: 882521c3b1e20a8bae181233b939174ee95e12a47bf62f41a62f1a20381a6f03
    

    如您所见,如果将04+X+Y连接起来,您将得到原始的公钥(04是未压缩的EC点标记)