我正在创建一个xml数字签名,就像我发现的几乎所有示例中提到的一样:
String providerName = System.getProperty("jsr105Provider",
"org.jcp.xml.dsig.internal.dom.XMLDSigRI");
XMLSignatureFactory fac =
XMLSignatureFactory.getInstance("DOM",
(Provider) Class.forName(providerName).newInstance());
...and so on...
我们将生成的xml文件发送给验证此签名的客户。所有的测试都通过了,直到现在一切正常。
在生产系统中,我们的客户突然发回“数字签名错误”。重新启动应用程序服务器后,所有内容都显示正常,并且客户已成功验证了某些文件。但是在几分钟/小时后,客户再次发回“数字签名错误”。只有重新启动应用程序服务器才能临时解决问题。
我发现是什么导致了这个问题,但我不明白。 在应用程序WSS4J的某处使用,初始化如下所示(org.apache.ws.security.WSSConfig):
public static synchronized void init() {
if (!staticallyInitialized) {
if (addJceProviders) {
setXmlSecIgnoreLineBreak();
AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
addXMLDSigRI(); <-- this line causes the problem
addJceProvider("BC", "org.bouncycastle.jce.provider.BouncyCastleProvider");
Security.removeProvider("STRTransform");
appendJceProvider(
"STRTransform", new org.apache.ws.security.transform.STRTransformProvider()
);
return true;
}
});
}
staticallyInitialized = true;
}
}
addXMLDsigRI()在当前提供程序配置(java.security)中不存在时,在第2位添加ApacheXMLDSig提供程序。默认的XMLDSig jdk提供程序位于第8位。
在初始化WSS4J之后,xml数字签名的创建发生了变化,客户说“数字签名错误”。
当我在第2位手动注册ApacheXMLDSig提供程序时,我可以重现客户错误。如果我在第10位添加提供程序(在jdk提供程序之后),它会再次运行。
版本:
我明确使用jdk提供程序: org.jcp.xml.dsig.internal.dom.XMLDSigRI
为什么apache提供程序的注册“破坏”了jdk提供程序的功能,我该如何解决?
答案 0 :(得分:1)
您可以通过调用:
来禁用WSS4J中Apache Santuario提供程序的注册WSSConfig.setAddJceProviders(假);
见这里:
答案 1 :(得分:1)
JDK注册了自己的xml安全提供程序版本,并且在Wss4j初始化时,XMLSignatureFactory来自JDK版本,而不是来自Xmlsec jar。 在Wss4j的较新版本中,此问题已在“ addXMLDSigRI()”中修复,如下所示:
Security.removeProvider("ApacheXMLDSig");
addJceProvider("ApacheXMLDSig", SantuarioUtil.getSantuarioProvider());
即,首先删除JDK注册的提供程序版本,然后注册它自己的版本。这样可以防止使用来自不同提供程序(例如Azul JDK)的JDK时引起的类加载问题。