首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.security.InvalidAlgorithmParameterException在Java 8上,但在Java 11上工作

java.security.InvalidAlgorithmParameterException在Java 8上,但在Java 11上工作
EN

Stack Overflow用户
提问于 2022-05-27 14:15:53
回答 1查看 205关注 0票数 0

因此,让我们假设您希望使用一个公钥验证签名,该公钥使用带有brainpoolP256r1椭圆曲线的ECDSA算法。

要运行下面的代码,请执行以下步骤:

  1. 使用以下命令生成脑池的键盘:

代码语言:javascript
复制
openssl ecparam -name brainpoolP256r1 -genkey -noout -out ec-brainpoolP256r1-priv-key.pem
openssl ec -in ec-brainpoolP256r1-priv-key.pem -pubout > ec-brainpoolP256r1-pub-key.pem
openssl pkcs8 -topk8 -nocrypt -in ec-brainpoolP256r1-priv-key.pem -out ec-brainpoolP256r1-priv-key-pkcs8.pem (to read it with tomitribe PEM utility, we need the PKCS8 format)

  1. 在使用生成的键后运行以下代码:

代码语言:javascript
复制
package com.test.ecdsa;

import org.tomitribe.auth.signatures.PEM;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

public class Main {
    public static void main(String[] args) throws Exception {
        String privateKeyPem = "[use here the content from ec-brainpoolP256r1-priv-key-pkcs8.pem]";

        Signature signer = Signature.getInstance("SHA256withECDSA");
        PrivateKey privateKey = PEM.readPrivateKey(new ByteArrayInputStream(privateKeyPem.getBytes(StandardCharsets.UTF_8)));

        signer.initSign(privateKey);
        signer.update("testMessage".getBytes(StandardCharsets.UTF_8));
        byte[] signature = signer.sign();

        String publicKeyPem = "[use here the content from ec-brainpoolP256r1-pub-key.pem]";

        PublicKey publicKey = PEM.readPublicKey(new ByteArrayInputStream(publicKeyPem.getBytes(StandardCharsets.UTF_8)));
        Signature signatureVerifier = Signature.getInstance("SHA256withECDSA");
        signatureVerifier.initVerify(publicKey);
        signatureVerifier.update("testMessage".getBytes(StandardCharsets.UTF_8));

        boolean result = signatureVerifier.verify(signature);

        System.out.println(result);
    }
}

在java 8上运行此代码将导致:

代码语言:javascript
复制
Exception in thread "main" java.security.SignatureException: Could not sign data
    at sun.security.ec.ECDSASignature.signDigestNative(ECDSASignature.java:367)
    at sun.security.ec.ECDSASignature.engineSign(ECDSASignature.java:386)
    at java.security.Signature$Delegate.engineSign(Signature.java:1382)
    at java.security.Signature.sign(Signature.java:698)
    at com.ing.obp.jws.lib.Main.main(Main.java:29)
Caused by: java.security.InvalidAlgorithmParameterException
    at sun.security.ec.ECDSASignature.signDigest(Native Method)
    at sun.security.ec.ECDSASignature.signDigestNative(ECDSASignature.java:364)
    ... 4 more

使用java 11,控制台将打印"true“。

为什么会这样呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-27 14:15:53

在java 11中添加了Brainpool和其他ECC支持(自从java 7之后,我发现这个链接非常有趣:https://bugs.openjdk.java.net/browse/JDK-7007966)

如果您仍然希望使用java 8来读取密钥、签名、验证签名,那么您将需要BouncyCastleProvider。

Maven依赖关系:

代码语言:javascript
复制
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

要使用它,您可以将提供程序注册到java的安全层,然后使用BouncyCastleProvider.PROVIDER_NAME在Signature.getInstance中引用它。

如下所示:

代码语言:javascript
复制
...
import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
public class Main {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
...
        Signature signer = Signature.getInstance("SHA256withECDSA", BouncyCastleProvider.PROVIDER_NAME);
...
        Signature signatureVerifier = Signature.getInstance("SHA256withECDSA", BouncyCastleProvider.PROVIDER_NAME);
...
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72406809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档