2017-06-01 88 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