ECDSA 私钥和 public 密钥 - 如何获取 SecretKey?

ECDSA private and public keys - how to get SecretKey?

我已经使用 generateKeyPair() 方法使用 ECDSA 算法生成了 2 个不同的 KeyPair

public KeyPair generateKeyPair(){           

    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp192r1");
    KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC");
    g.initialize(spec, new SecureRandom());

    return g.generateKeyPair(); 
}

然后我使用来自单独 KeyPairPrivateKeyPublicKey 来合并 SecretKey:

private SecretKey generateSecretKey(PrivateKey privateKey, PublicKey publicKey) {

    KeyAgreement ka = KeyAgreement.getInstance("ECDH");
    ka.init(privateKey);
    ka.doPhase(publicKey),
            true);

    return ka.generateSecret("AES");
}

但我得到 ka.generateSecret("AES"):

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi.engineGenerateSecret(Unknown Source)
    at javax.crypto.KeyAgreement.generateSecret(KeyAgreement.java:648)

如果我使用 ECDSA,我得到:

Exception in thread "main" java.security.NoSuchAlgorithmException: Algorithm ECDSA not available
   at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:184)

使用 DH 抛出:

Exception in thread "main" java.security.InvalidKeyException: DHKeyAgreement requires DHPrivateKey
    at org.bouncycastle.jcajce.provider.asymmetric.dh.KeyAgreementSpi.engineInit(Unknown Source)
    at javax.crypto.KeyAgreement.implInit(KeyAgreement.java:346)
    at javax.crypto.KeyAgreement.chooseProvider(KeyAgreement.java:378)
    at javax.crypto.KeyAgreement.init(KeyAgreement.java:470)

如何从使用 ECDSA 算法生成的 PrivateKeyPublicKey 中合并 SecretKey

密钥协商协议通常在两方之间工作,每一方都有自己的 ECDS public 和私钥(因此我们有四个不同的密钥)。你确定那是你想要的吗?

因此,当您同意密钥时,您需要甲方的私钥和乙方的public密钥.在连接的另一端,您使用乙方的私钥和甲方的 public 密钥。

您选择的 ECDH 密钥协商算法在 RFC3278 中进行了描述 - 有关详细信息,请阅读。

return ka.generateSecret(); 中删除 "AES" 参数后,它工作正常并且 returns 曲线大小共享秘密:

private SecretKey generateSecretKey(PrivateKey privateKey, PublicKey publicKey) {

    KeyAgreement ka = KeyAgreement.getInstance("ECDH");
    ka.init(privateKey);
    ka.doPhase(publicKey, true);

    return ka.generateSecret();
}