Java - 使用 ECDSA(椭圆曲线)创建 XML 数字签名

Posted

技术标签:

【中文标题】Java - 使用 ECDSA(椭圆曲线)创建 XML 数字签名【英文标题】:Java - Create XML Digital Signature using ECDSA (Elliptic Curve) 【发布时间】:2018-08-22 07:26:15 【问题描述】:

我们可以使用 RSA 密钥创建 XML 数字签名。但是如何使用椭圆曲线密钥来签署 xml 文件?我收到错误消息,例如 -

Exception in thread "main" java.security.KeyException: ECKeyValue not supported
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:350)
    at org.jcp.xml.dsig.internal.dom.DOMKeyInfoFactory.newKeyValue(DOMKeyInfoFactory.java:71)
    at csr.ExtractEC.main(XMLSignatureECTest.java:57)
Caused by: java.lang.ClassNotFoundException: sun/security/ec/ECParameters
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.getMethods(DOMKeyValue.java:367)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:343)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC$1.run(DOMKeyValue.java:339)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.jcp.xml.dsig.internal.dom.DOMKeyValue$EC.<init>(DOMKeyValue.java:338)
    ... 2 more

我使用下面的代码来创建 SignatureMethod 和 KeyInfo -

String url = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
        SignatureMethod signatureMethod = factory.newSignatureMethod(url, null);
        SignedInfo signedInfo = factory.newSignedInfo(c14n, signatureMethod, Collections.singletonList(reference));

        PrivateKey privateKey = Utils.generatePrivateEC("e:\\certs\\ec\\ec.key.p8");
        Certificate certificate = Utils.generatePublic("e:\\certs\\ec\\ec.cer");
        KeyInfoFactory keyInfoFactory = factory.getKeyInfoFactory();
        KeyValue keyValue = keyInfoFactory.newKeyValue(certificate.getPublicKey());
        KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(keyValue));

JDK - Oracle JDK 8 安全提供商 - BouncyCastle 和 Sun。

【问题讨论】:

我不明白为什么人们只是对任何问题投反对票,如果他们不感兴趣的话。他们给社区制造了问题。 这不仅仅是投反对票。没有minimal reproducible example 没有关于你使用哪个 JDK/JRE 的信息 也许this 有帮助 @Jens:呃,没有给出解决方法。 发生了什么真的很奇怪:它在 Class.forName("sun.security.ec.ECParameters") 上失败,但如果你静态访问同一个类,或者自己调用 Class.forName 它工作,只有稍后在库调用中失败。他们在搞乱类加载器吗?! 【参考方案1】:

似乎在this junit test 有人为你做榜样。

【讨论】:

以上是关于Java - 使用 ECDSA(椭圆曲线)创建 XML 数字签名的主要内容,如果未能解决你的问题,请参考以下文章

golang 椭圆曲线加密使用ecdsa

如何使用椭圆曲线私钥和 ECDSA 算法签署证书?

算法2_非对称加密算法之ECDSA(椭圆曲线数字签名算法)

ECDSA数字签名算法

椭圆曲线密码学ECC

在 .NET 中加载椭圆曲线 (EC) 密钥