【问题标题】:Generate ECPublicKey from ECPrivateKey从 ECPrivateKey 生成 ECPublicKey
【发布时间】:2017-07-27 03:34:30
【问题描述】:

我正在尝试在给定私钥和已知曲线的情况下生成公钥。以下是我的代码:

// Generate Keys
ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("secp256r1");
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC");
keyPairGenerator.initialize(ecGenSpec, new SecureRandom());
java.security.KeyPair pair = keyPairGenerator.generateKeyPair();
ECPrivateKey privateKey = (ECPrivateKey) pair.getPrivate();
ECPublicKey publicKeyExpected = (ECPublicKey) pair.getPublic();

// Expected public key
System.out.print("Expected Public Key: " +
        BaseEncoding.base64Url().encode(publicKeyExpected.getEncoded()));

// Generate public key from private key
X9ECParameters ecp = SECNamedCurves.getByName("secp256r1");
ECDomainParameters domainParams = new ECDomainParameters(ecp.getCurve(),
        ecp.getG(), ecp.getN(), ecp.getH(),
        ecp.getSeed());
ECPoint Q = domainParams.getG().multiply(privateKey.getS()); // is this correct?
KeyFactory kf = KeyFactory.getInstance("ECDSA", "BC");
ECPublicKey publicKeyGenerated =
        (ECPublicKey) kf.generatePublic(new X509EncodedKeySpec(Q.getEncoded(false)));  // exception here

// Generated public key from private key
System.out.print("Generated Public Key: " +
        BaseEncoding.base64Url().encode(publicKeyGenerated.getEncoded()));

但是,当我打电话时:kf.generatePublic(new X509EncodedKeySpec(Q.getEncoded(false))) 我得到了例外:java.security.spec.InvalidKeySpecException: encoded key spec not recognised(不是我的拼写错误)

我似乎错误地计算了Q,但我不确定我的错误在哪里。

感谢您的帮助!

【问题讨论】:

  • 为什么你认为可以从私钥中得到公钥?
  • 如果你知道曲线,使用 ECC 只是点乘法 (secp256r1)
  • 我希望反过来不是这样。我的意思是,我希望不能只知道公钥和曲线就获得ECC私钥。是吗?

标签: java security cryptography bouncycastle public-key


【解决方案1】:

@markw 的答案进行了一些改进,并通过@bas-goossen 从这里扩展了曲线名称检测:How to find the matching curve name from an ECPublicKey

public static ECPublicKey publicFromPrivate(final ECPrivateKey privateKey) throws Exception {
    ECParameterSpec params = privateKey.getParams();
    org.bouncycastle.jce.spec.ECParameterSpec bcSpec = org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util
        .convertSpec(params, false);
    org.bouncycastle.math.ec.ECPoint q = bcSpec.getG().multiply(privateKey.getS());
    org.bouncycastle.math.ec.ECPoint bcW = bcSpec.getCurve().decodePoint(q.getEncoded(false));
    ECPoint w = new ECPoint(
        bcW.getAffineXCoord().toBigInteger(),
        bcW.getAffineYCoord().toBigInteger());
    ECPublicKeySpec keySpec = new ECPublicKeySpec(w, tryFindNamedCurveSpec(params));
    return (ECPublicKey) KeyFactory
        .getInstance("EC", org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME)
        .generatePublic(keySpec);
}

@SuppressWarnings("unchecked")
public static ECParameterSpec tryFindNamedCurveSpec(ECParameterSpec params) {
    org.bouncycastle.jce.spec.ECParameterSpec bcSpec
        = org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertSpec(params, false);
    for (Object name : Collections.list(org.bouncycastle.jce.ECNamedCurveTable.getNames())) {
        org.bouncycastle.jce.spec.ECNamedCurveParameterSpec bcNamedSpec
            = org.bouncycastle.jce.ECNamedCurveTable.getParameterSpec((String) name);
        if (bcNamedSpec.getN().equals(bcSpec.getN())
            && bcNamedSpec.getH().equals(bcSpec.getH())
            && bcNamedSpec.getCurve().equals(bcSpec.getCurve())
            && bcNamedSpec.getG().equals(bcSpec.getG())) {
            return new org.bouncycastle.jce.spec.ECNamedCurveSpec(
                bcNamedSpec.getName(),
                bcNamedSpec.getCurve(),
                bcNamedSpec.getG(),
                bcNamedSpec.getN(),
                bcNamedSpec.getH(),
                bcNamedSpec.getSeed());
        }
    }
    return params;
}

【讨论】:

    【解决方案2】:

    如果我未来的自己需要解决方案:

    // Generate Keys
    ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("secp256r1");
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC");
    keyPairGenerator.initialize(ecGenSpec, new SecureRandom());
    java.security.KeyPair pair = keyPairGenerator.generateKeyPair();
    ECPrivateKey privateKey = (ECPrivateKey) pair.getPrivate();
    ECPublicKey publicKeyExpected = (ECPublicKey) pair.getPublic();
    
    // Expected public key
    System.out.print("Expected Public Key: " +
            BaseEncoding.base64Url().encode(publicKeyExpected.getEncoded()));
    
    // Generate public key from private key
    KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
    ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
    
    ECPoint Q = ecSpec.getG().multiply(privateKey.getD());
    byte[] publicDerBytes = Q.getEncoded(false);
    
    ECPoint point = ecSpec.getCurve().decodePoint(publicDerBytes);
    ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, ecSpec);
    ECPublicKey publicKeyGenerated = (ECPublicKey) keyFactory.generatePublic(pubSpec);
    
    // Generated public key from private key
    System.out.print("Generated Public Key: " +
            BaseEncoding.base64Url().encode(publicKeyGenerated.getEncoded()));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多