当前位置: 首页 > 知识库问答 >
问题:

Java语言安全Java 8上的InvalidAlgorithmParameterException可用于Java 11

白成济
2023-03-14

所以,假设您想使用公钥验证签名,该公钥使用ECDSA算法和brainpoolP256r1椭圆曲线。

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

  1. 使用以下命令生成脑池密钥对:
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)
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上运行此代码将导致:

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”。

那是为什么呢?

共有1个答案

欧阳何平
2023-03-14

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

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

Maven依赖:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

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

像这样:

...
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);
...
}

 类似资料:
  • 我在JRE 1.8(jdk1.8.0\U 101)上使用SSL从JBoss连接IBM MQ时遇到问题 我在下面一行评论java。安全但无任何变化: 更新:在进行以下更改后,出现如下新错误:TLS\U RSA\U WITH\U AES\U 128\U CBC\U SHA256 JVM参数已添加:-Dcom。ibm。mq。cfg公司。useIBMCipherMappings=false javax.n

  • 我已经创建了谷歌应用程序引擎项目,使用预测Api 1.5v。当我在本地均值localhost:8888使用谷歌o2Auth身份验证与客户端ID和客户端运行时,它对我来说工作正常secret.but当我实时运行它时,它会给出一个错误 Java语言安全AccessControlException:访问被拒绝(“java.io.FilePermission”“/base/data/home/apps/s

  • 我有一个方法,它将和作为参数,查询数据库,并实现一些逻辑,以逗号分隔的字符串查找该可以访问的URL。 我想开发此方法的空安全版本,使用相同的和作为参数,然后返回一个,如果传递给它的值中至少有一个为空或方法返回,则该值将为空。我写了下面的代码,但它看起来像是一个基于空检查的实现,我看不到使用Optional使代码更简洁的好处。 有没有更好的方法让代码更具可读性?

  • 本文向大家介绍C语言new操作的安全性分析,包括了C语言new操作的安全性分析的使用技巧和注意事项,需要的朋友参考一下 对于学习过C语言的朋友应该都知道,使用 malloc/calloc 等分配内存的函数时,一定要检查其返回值是否为“空指针”(亦即检查分配内存的操作是否成功),这是良好的编程习惯,也是编写可靠程序所必需的。但是,如果你简单地把这一招应用到new上,那可就不一定正确了。我经常看到类似

  • 这是个例外 这是我的密码

  • 问题内容: 我在Android的OpenGL-ES 3.0中使用的工作代码如下所示: 我的问题是在第三行上将结果转换为to 。被声明为返回一个: 在我的测试平台上,该函数返回的子类,因此强制转换有效,但对于支持OpenGL-ES 3+的所有平台或Android版本进行此假设似乎并不十分安全。尽管看起来很合理,但我还没有找到任何可以保证它的文档,如果可以保证,似乎应该将该函数声明为returning