Java Bouncycastle XmlSignatureFactory无此算法异常
我在使用BouncyCastle检查XMLSignature以验证使用ECDSA的信号时遇到问题 以下是相关代码行:Java Bouncycastle XmlSignatureFactory无此算法异常,java,bouncycastle,xml-signature,Java,Bouncycastle,Xml Signature,我在使用BouncyCastle检查XMLSignature以验证使用ECDSA的信号时遇到问题 以下是相关代码行: BouncyCastleProvider provider = new BouncyCastleProvider(); Security.addProvider(provider); //some unrelated code XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM", provi
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
//some unrelated code
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM", provider);
在最后一行,将在中引发以下异常:
javax.xml.crypto.NoSuchMechanismException: java.security.NoSuchAlgorithmException: no such algorithm: DOM for provider SC
如果我把线路改成
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
我明白了
javax.xml.crypto.MarshalException: unsupported SignatureMethod algorithm: http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160
有人知道这是什么原因吗?在第一个错误中,您可以在错误描述中读到“没有这样的算法:DOM for provider SC”。这很奇怪,因为它说的是“提供商SC”(Sun PC/SC提供商)而不是“提供商BC”(BouncyCastle安全提供商)。看起来您的代码(内部)没有按照您的需要使用Bouncycastle。你应该找出发生这种情况的原因。它可能是关于BC库和类路径(如果您正在使用应用程序服务器)或提供者顺序配置的内容 第二个错误。您改变了获取XMLSignatureFactory的方法。这一个更好,因为如果不指定提供程序,因为: 此方法使用标准JCA提供程序查找机制来查找 并实例化所需对象的XMLSignatureFactory实现 机构类型。它遍历已注册安全性的列表 提供程序,从最首选的提供程序开始。一个新的 来自支持的第一个提供程序的XMLSignatureFactory对象 返回指定的机制 但现在,算法并不存在。那么,为什么呢?在这里,我要说的是BC没有被使用。它在那里?回顾你的类路径 列出所有可用的提供商可能会有所帮助:
for (Provider p : Security.getProviders()) {
log.debug(p.getName());
log.debug(p.getInfo());
}
在第一个错误中,您可以在错误描述中读取“没有这样的算法:DOM for provider SC”。这很奇怪,因为它说的是“提供商SC”(Sun PC/SC提供商)而不是“提供商BC”(BouncyCastle安全提供商)。看起来您的代码(内部)没有按照您的需要使用Bouncycastle。你应该找出发生这种情况的原因。它可能是关于BC库和类路径(如果您正在使用应用程序服务器)或提供者顺序配置的内容 第二个错误。您改变了获取XMLSignatureFactory的方法。这一个更好,因为如果不指定提供程序,因为: 此方法使用标准JCA提供程序查找机制来查找 并实例化所需对象的XMLSignatureFactory实现 机构类型。它遍历已注册安全性的列表 提供程序,从最首选的提供程序开始。一个新的 来自支持的第一个提供程序的XMLSignatureFactory对象 返回指定的机制 但现在,算法并不存在。那么,为什么呢?在这里,我要说的是BC没有被使用。它在那里?回顾你的类路径 列出所有可用的提供商可能会有所帮助:
for (Provider p : Security.getProviders()) {
log.debug(p.getName());
log.debug(p.getInfo());
}
从第二个异常中猜测,因为要验证xml签名, 您可能已经使用了一些代码,如下面的代码 但是xml表示有如下内容
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue>
</Reference>
</SignedInfo>
...
</Signature>
只需进入DOMSignatureMethod.unmarshal
static方法一步,它使用http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160
查找数字签名算法,
但是DOMSignatureMethod
只支持以下算法
rsa-sha1
rsa-sha256
rsa-sha384
rsa-sha512
dsa-sha1
dsa-sha256
hmac-sha1
hmac-sha256
hmac-sha384
hmac-sha512
ecdsa-sha1
ecdsa-sha256
ecdsa-sha384
ecdsa-sha512
解决方案是:
将BC提供程序添加到安全性中,并使用org.apache.santuario-xmlsec项目中的XMLSignature进行验证
public boolean verify(String signedXML) throws Exception {
Document doc = null;
try (InputStream is = new ByteArrayInputStream(signedXML.getBytes(Charset.forName("utf-8")))) {
doc = MyXMLUtils.read(is, false);
}
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
xpath.setNamespaceContext(new DSNamespaceContext());
String expression = "//ds:Signature[1]";
Element sigElement =
(Element) xpath.evaluate(expression, doc, XPathConstants.NODE);
XMLSignature signature = new XMLSignature(sigElement, "");
KeyInfo ki = signature.getKeyInfo();
if (ki == null) {
throw new RuntimeException("No keyinfo");
}
PublicKey pk = signature.getKeyInfo().getPublicKey();
if (pk == null) {
throw new RuntimeException("No public key");
}
return signature.checkSignatureValue(pk);
}
来自repo的更多演示:根据第二个异常猜测,因为您希望验证xml签名, 您可能已经使用了一些代码,如下面的代码 但是xml表示有如下内容
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue>
</Reference>
</SignedInfo>
...
</Signature>
只需进入DOMSignatureMethod.unmarshal
static方法一步,它使用http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160
查找数字签名算法,
但是DOMSignatureMethod
只支持以下算法
rsa-sha1
rsa-sha256
rsa-sha384
rsa-sha512
dsa-sha1
dsa-sha256
hmac-sha1
hmac-sha256
hmac-sha384
hmac-sha512
ecdsa-sha1
ecdsa-sha256
ecdsa-sha384
ecdsa-sha512
解决方案是:
将BC提供程序添加到安全性中,并使用org.apache.santuario-xmlsec项目中的XMLSignature进行验证
public boolean verify(String signedXML) throws Exception {
Document doc = null;
try (InputStream is = new ByteArrayInputStream(signedXML.getBytes(Charset.forName("utf-8")))) {
doc = MyXMLUtils.read(is, false);
}
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
xpath.setNamespaceContext(new DSNamespaceContext());
String expression = "//ds:Signature[1]";
Element sigElement =
(Element) xpath.evaluate(expression, doc, XPathConstants.NODE);
XMLSignature signature = new XMLSignature(sigElement, "");
KeyInfo ki = signature.getKeyInfo();
if (ki == null) {
throw new RuntimeException("No keyinfo");
}
PublicKey pk = signature.getKeyInfo().getPublicKey();
if (pk == null) {
throw new RuntimeException("No public key");
}
return signature.checkSignatureValue(pk);
}
repo的更多演示:BouncyCastle Security Provider v1.46在我列出所有Providers时被列出。我们看到完整的条目是:“name:SC”“info:BouncyCastle Security Provider v1.46”,所以SC是BouncyCastleprovider。确定吗?看看这个:当我列出提供商BouncyCastle的名字是“BC”时,我只能告诉你我看到了什么,日志上写着SC=BouncyCastle Security Provider^^^你解决过这个问题吗?我无法从答案或评论中判断。问题是Bouncy Castle没有为XmlSignatureFactory提供服务,当我列出所有提供程序时,会列出AFAIC.BouncyCastle安全提供程序v1.46。我们看到完整的条目是:“name:SC”“info:BouncyCastle安全提供程序v1.46”,所以SC就是BouncyCastle提供程序。确定吗?看看这个:当我列出提供商BouncyCastle的名字是“BC”时,我只能告诉你我看到了什么,日志上写着SC=BouncyCastle Security Provider^^^你解决过这个问题吗?我无法从答案或评论中判断。问题是Bouncy Castle没有为XmlSignatureFactory AFAIC提供服务。