【问题标题】:ECDSA private and public keys - how to get SecretKey?ECDSA 私钥和公钥 - 如何获取 SecretKey?
【发布时间】:2017-04-02 10:16:56
【问题描述】:

我已经使用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(); 
}

然后我使用 PrivateKeyPublicKey 从单独的 KeyPair 合并 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

【问题讨论】:

  • 您使用哪个版本的 BouncyCastle?还要确保不要使用 OpenJDK,因为它在某些 Linux 发行版中缺少 ECDSA 支持。
  • bcpkix-jdk15on 1.54。它适用于 Windows 和 Linux 中的签名和验证。
  • 我不知道 BouncyCastle,但查看您的代码,我注意到一些可能导致问题的事情。首先,您似乎正在生成 ECDSA 密钥,但试图在 DH 密钥协议中使用它们——也许密钥格式错误?其次,您需要向KeyAgreement 对象提供曲线详细信息吗?我看到它提供了an overloaded init method that accepts an AlgorithmParameterSpec
  • 如果我将 ECDSA 用于 KeyAgreement,我会收到异常“算法 ECDSA 不可用”。当提供曲线规格时,它会抛出“不支持的参数”。但是,如果我 generateSecret("DES") 而不是 AES,效果会很好。

标签: encryption aes bouncycastle elliptic-curve ecdsa


【解决方案1】:

return ka.generateSecret(); 中删除“AES”参数后,它可以正常工作并返回曲线大小共享密钥:

private SecretKey generateSecretKey(PrivateKey privateKey, PublicKey publicKey) {

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

    return ka.generateSecret();
}

【讨论】:

  • 它对我有用。如何将密钥转换为字符串?
  • 将字节转换为 Hex 或 Base64 字符串。
【解决方案2】:

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

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

RFC3278 中描述了您选择的 ECDH 密钥协商算法 - 详情请阅读。

【讨论】:

  • 我知道,我使用来自不同密钥对的私钥和公钥。问题是生成 SecretKey 时出现异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
相关资源
最近更新 更多