【问题标题】:ECDSA signature generation using secp256r1 curve and SHA256 algorithm - BouncyCastle使用 secp256r1 曲线和 SHA256 算法生成 ECDSA 签名 - BouncyCastle
【发布时间】:2014-10-05 09:01:45
【问题描述】:

我正在尝试使用 ECDSA 和 secp256r1 曲线 (P256) 和 SHA256 算法为消息哈希生成签名。我也在使用 Bouncy Castle 库。 代码如下,

public class MyTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new MyTest().getSign();
    }

    void getSign() {
        // Get the instance of the Key Generator with "EC" algorithm

        try {
            KeyPairGenerator g = KeyPairGenerator.getInstance("EC");
            ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
            g.initialize(kpgparams);

            KeyPair pair = g.generateKeyPair();
            // Instance of signature class with SHA256withECDSA algorithm
            Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
            ecdsaSign.initSign(pair.getPrivate());

            System.out.println("Private Keys is::" + pair.getPrivate());
            System.out.println("Public Keys is::" + pair.getPublic());

            String msg = "text ecdsa with sha256";//getSHA256(msg)
            ecdsaSign.update((msg + pair.getPrivate().toString())
                    .getBytes("UTF-8"));

            byte[] signature = ecdsaSign.sign();
            System.out.println("Signature is::"
                    + new BigInteger(1, signature).toString(16));

            // Validation
            ecdsaSign.initVerify(pair.getPublic());
            ecdsaSign.update(signature);
            if (ecdsaSign.verify(signature))
                System.out.println("valid");
            else
                System.out.println("invalid!!!!");

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }

}

这里的密钥对是使用 KeyPair 生成的,但根据我的要求,我将拥有一个静态的 privateKey 和 public 密钥。此外,签名验证总是返回 false。

需要帮助,我怎样才能拥有静态私钥和验证部分。

【问题讨论】:

    标签: java bouncycastle sha256 ecdsa


    【解决方案1】:

    大奖 - 您的标题中没有任何问题!

    首先,您可能实际上并没有使用 BouncyCastle。 Sun/Oracle Java 7 和 8 现在包括一个 EC 提供程序(早期版本没有),getInstance 的单参数形式使用第一个可用的提供程序,通常是 SunEC,除非您或其他人更改了提供程序列表。

    验证签名:相同数据传递给验证Signature.update(),就像传递给签名Signature.update()一样。 一模一样,一个字节一个字节。 only 将签名值传递给Signature.verify()。将PrivateKey.toString() 放入数据中是愚蠢的;此值特定于正在运行的 Java 进程,因此您必须将其发送到接收进程(如果不同,通常应该如此),在那里它无用且浪费空间。

    使用静态键: 这样做。创建一个密钥对并将其存储在某个地方,然后读入并使用它。最简单的安全(受密码保护)存储是 Java KeyStore (JKS) 文件,但这需要证书链(可能是虚拟的),这对您自己进行编码很麻烦;幸运的是,带有-genkeypairkeytool 实用程序会生成一个带有虚拟自签名证书的密钥对,而对于-keyalg ec -keysize 256,它使用(非常流行的)secp256r1 曲线。还要指定您选择的-alias name-keystore filename、您喜欢的虚拟证书名称和密码。要使用 JKS 文件中的密钥对:

    • 使用java.security.KeyStore.getInstance("JKS") 创建一个存储对象并在文件上传递.load(InputStream,char[])FileInputStream 以及密码。

    • 使用.getKey(String alias,char[] password) 并强制转换以获取 PrivateKey。用于签名。

    • 使用.getCertificateChain(String alias)[0].getPublicKey() 从第一个(唯一的)证书中获取公钥。用于验证。

    【讨论】:

    • 谢谢 Dave,糟糕,这是 Signature.update() 中的错误。我能够验证签名:)。 m 现在在静态私钥上。应尝试您提供的选项。
    【解决方案2】:

    我已决定将初始问题的代码更新为最终工作版本,以供未来读者使用。

        try {
            KeyPairGenerator kg = KeyPairGenerator.getInstance("EC");
            ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
            kg.initialize(kpgparams);
    
            KeyPair kp = kg.generateKeyPair();
            PublicKey pubKey = kp.getPublic();
            PrivateKey pvtKey = kp.getPrivate();
    
            // sign
            Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
            ecdsaSign.initSign(pvtKey);
            String message = "text ecdsa with sha256";//getSHA256(msg)
            ecdsaSign.update(message.getBytes(StandardCharsets.UTF_8), 0, message.length());
            byte[] signature = ecdsaSign.sign();
    
            // Validation
            ecdsaSign.initVerify(pubKey);
            ecdsaSign.update(message.getBytes(StandardCharsets.UTF_8), 0, message.length());
            boolean result = ecdsaSign.verify(signature);
    
            assertTrue(result); // junit5 assert
        } catch (Exception e) {
             e.printStackTrace();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多