java - 使用 secp256r1 曲线和 SHA256 算法生成 ECDSA 签名 - BouncyCaSTLe

标签 java bouncycastle sha256 ecdsa

我正在尝试使用带有 secp256r1 曲线 (P256) 的 ECDSA 和用于消息哈希的 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();
        }

    }

}

此处的 key 对是使用 KeyPair 生成的,但根据我的要求,我将拥有静态私钥和公钥。此外,签名验证始终返回 false。

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

最佳答案

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

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

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

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

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

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

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

关于java - 使用 secp256r1 曲线和 SHA256 算法生成 ECDSA 签名 - BouncyCaSTLe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25261823/

相关文章:

java - Serializable - writeObject()/ReadObject 和 Externalizable - Java 中的 readExternal()/writeExternal() 有什么区别?

java - 单击文本字段并清除文本?

java - 运行 Gradle 导致 - 错误 : Could not find or load main class security. provider.1=org.bouncycaSTLe.jce.provider.BouncyCaSTLeProvider

php - 检查 mysql 中的 SHA256 哈希密码在登录表单中是否正确不起作用

java - 使用 Java 获取用户输入并在 boolean 函数中使用它?

java - 自生成的公钥确实具有相同的开头

java - 该程序编译完美,但在运行时导入的类出现问题

django - 在 Node.js 应用程序中使用 BCryptSHA256PasswordHasher 验证在 Django 中哈希的密码

javascript - 对表单数据的代码哈希函数 - 已经有函数但不知道在哪里调用

java - 在 tomcat 上运行简单的 hello restapi 时出现 404 响应