2017-06-01 89 views
1

做的工作:摘要计算失败在Windows,Java的1.8

我有一个签名的SOAP请求,我要检查,如果签名是好的。 SOAP消息的时间戳不重要。

我到目前为止的解决方案:

我做了一个子类org.apache.wss4j.dom.engine.WSSecurityEngine,其中在方法processSecurityHeader TimestampProcessor的检验结果是取出关注:

public class SignatureSecurityEngine extends WSSecurityEngine { 
... 
    public WSHandlerResult processSecurityHeader(Element securityHeader, RequestData requestData) throws org.apache.wss4j.common.ext.WSSecurityException { 
    ... 
     Processor p = cfg.getProcessor(el); 
     if (p != null) { 
     try { 
      results = p.handleToken((Element) node, requestData, wsDocInfo); 
     } catch (Exception e){ 
      if (p instanceof TimestampProcessor) { 
       // it's okay if timestamp is too old 
      } else { 
       throw e; 
      } 
     } 
     } 
... 

实际上它只是WSSecurityEngine的一个副本,其中添加了用于时间戳处理器的try/catch。

我旧版本的wss4j和xmlsec工作正常。

组件的版本升级后,我得到了以下奇怪的问题:

签名的计算消化在org.apache.jcp.xml.dsig.internal.dom.DOMReference.validate失败 (...),如果:

  • 的PROGRAMM在Windows上运行(JRE)
  • 我调试在Windows(JDK)
  • 我调试在Linux(JDK)

但是:

如果PROGRAMM在Linux(JRE)运行,一切正常!

对于(在Windows/Linux的),配置为:

  • WSS4J 2.1.9
  • xmlsec 2.0.8
  • Java版本:1.8.0_131(建1.8.0_131 -B11)

观察:

对于计算出的摘要,似乎仍有一个标准值(2jmj7l5rSw0yVb/vlWAYkK/YBwk =)。

有什么想法?


其他事实(2017年6月13日):

后Maartens句话我(重新)写了一些类(其实复制粘贴&),并增加了一些的System.out.println在运行时拥有“调试信息”。真的是一个古怪的风格和丑陋的东西... 但结果相当有趣!

  1. MessageDigest的流从未设置过。因此,这解释了2jmj7l5rSw0yVb/vlWAYkK/YBwk =这是消化与SHA-1空字符串

我设法再修复(感谢马腾!) - 这样的数据流,现在在我的复制设置“调试” - 班。

结果:如果我现在用我的IDE进行调试,计算功能!

但是:如果我在运行时运行检查失败: - (((理由:计算出的值不等于预期

进一步观察表明:EV的错误的计算依赖于消化有要计算的数据的长度

让我们看看我的日志(!?!?!?)。

*** Digest for Timestamp 
VGDOMReference.validate -> transform: 
Expected digest: LxfIdEUVsbyLaevptByfIf2L0PA= 
Actual digest: LxfIdEUVsbyLaevptByfIf2L0PA= 
Reference[#Timestamp-31b20235-a1e2-4ed0-9658-67611572108e] 
*** Digest for Body 
Expected digest: Yv+zLpkog+xzAdMlSjoIaZntZLs= 
Actual digest: sj2Gb0GEyjWuxoCmnBzDY266aG8= 
Reference[#Body-c9761a98-46bb-4175-8f8b-bfa9b5c75509] 

正如你所看到的时间戳计算是正确的。但身体的一个是错了

也许有些流缓冲区没有完全写入?

+0

例外/堆栈跟踪可再现的测试条件下,配置 – eis

+0

在DOMReference.validate当心(? ...):你有这个.digestValue {取自fi le}和this.calcDigestValue {新计算}。该行this.validationStatus = Arrays.equals(this.digestValue,this.calcDigestValue); validationStatus的结果为false。它似乎是独立于您所采用的soap签名文件,calcDigestValue的结果始终为2jmj7l5rSw0yVb/vlWAYkK/YBwk = – jahuer1

+0

在任何与XML签名验证有关的场景中,您都必须确保引用/名称空间是正确的。我不得不明确地添加检查,因为XML digsig使用了一个路径,而SOAP是一个元素的ID(或者是相反的方式?)。如果每次参考可能关闭时都会得到相同的散列值。请注意,您的摘要值是**空字符串**的SHA-1哈希值。 –

回答

0

一些测试后,事实证明,有一个额外的编码问题... ...: - (((

原始签名的文件是UTF-8,但Windows使用ISO-xyz_whatever它不匹配。

首先解决方法是把JVM的编码,即调用罐子脚本,所以:

java -Dfile.encoding=UTF8 <programm>.jar 
+1

更好的解决方法是在将文件中的字节转换为字符时指定编码。如果没有完整的代码,我不知道你错在哪里,但这通常发生在InputStreamReader中。 –

+0

如果这样可以解决问题,那么您应该通过在读取文件的位置显式指定编码来修复应用程序,而不是覆盖默认文件编码的权宜计量措施。 –

+0

了解编码问题,我们调整了10多年前阅读的文件...。关键是,在更新第三方组件时出现错误。 wss4j从1.5.8到2.1.9; xmlsec作为新的依赖关系。那里肯定有一些非常隐蔽的bug。另一方面,如果我在Windows机器上运行实际上使用相同类的webservice项目,则没有问题...(!?!?!?) – jahuer1