2011-11-13 13 views
2

Apache Santuario Javaライブラリバージョン1.4.6を使用してXML署名を検証する際の問題を解決するための助けが必要です。私はクライアントがドキュメントをサーバーに送る前にDOMドキュメントに署名するクライアント/サーバーソリューションを持っています。私はそうのような文書に署名を適用します。次のようにApache Santuario 1.4.6を使用してXML署名を検証できません。

public static void applySignature(X509Certificate cert, PrivateKey privateKey, Document doc) 
{ 
    try 
    { 
     XMLSignature sig = new XMLSignature(doc, 
              "", 
              XMLSignature.ALGO_ID_SIGNATURE_RSA); 

     sig.addResourceResolver(new XmlSignatureResolver()); 
     doc.getDocumentElement().appendChild(sig.getElement()); 

     Transforms transforms = new Transforms(doc); 
     transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE); 
     transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS); 

     sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1); 

     sig.addKeyInfo(cert); 
     sig.addKeyInfo(cert.getPublicKey()); 

     sig.sign(privateKey); 
    } 
    catch (XMLSecurityException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

は私が署名を検証:

public static boolean verifySignature(X509Certificate cert, Document doc) 
{ 
    boolean validSignature = false; 

    try 
    { 
     Element nscontext = createDSctx(doc, "ds", Constants.SignatureSpecNS); 

     // Remove any attributes of Signed Info 
     Node signInfoNode = XPathAPI.selectSingleNode(doc, "//ds:SignedInfo", nscontext); 

     int numAttributes = signInfoNode.getAttributes().getLength(); 
     if (numAttributes > 0) 
     { 
      for (int i = 0; i < numAttributes; i++) 
      { 
       String attrName = signInfoNode.getAttributes().item(0).getNodeName(); 
       signInfoNode.getAttributes().removeNamedItem(attrName); 
      }  
     } 

     Element sigElement = 
      (Element) XPathAPI.selectSingleNode(doc, "//ds:Signature", nscontext); 
     XMLSignature signature = new XMLSignature(sigElement, ""); 

     signature.setFollowNestedManifests(true); 
     signature.addResourceResolver(new XmlSignatureResolver()); 

     validSignature = signature.checkSignatureValue(cert); 

     // Remove the signature 
     sigElement.getParentNode().removeChild(sigElement);    
    } 
    catch (XMLSignatureException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    catch (XMLSecurityException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    catch (TransformerException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return validSignature;// validSignature; 
} 

私が持っている問題は、私は、サーバー上の署名を検証するとき(それが上で動作することです

2011年11月12日18時30分27秒参考[WARN]検証は、URI に失敗しました「」
201:私は)署名を適用した後、右を確認した場合、クライアント、私は次の警告を取得します1-11-12 18時30分27秒リファレンス[WARN]はダイジェスト予想: EEL + J/jsY8Im2rgjsozBXRx​​kQjQ =
2011年11月12日18時30分27秒リファレンス[WARN] 実際のダイジェスト:Y7C0HCjugZbegkZT4E8A7Bd4qm0 =

助けを

おかげで、
アーニーBurlison

=============

私はクライアントからサーバにDOMを送信するために使用するコードは次のとおりです。

   // Use a Transformer for output 
       TransformerFactory tFactory = TransformerFactory.newInstance(); 
       Transformer transformer = tFactory.newTransformer(); 
       transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
       transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); 
       transformer.setOutputProperty(OutputKeys.INDENT, "no"); 

       DOMSource source = new DOMSource(doc); 
       StreamResult result = new StreamResult(m_SenderOutput); 

       m_Logger.debug("Transforming..."); 
       transformer.transform(source, result); 
       m_SenderOutput.flush(); 
       m_Logger.debug("Transform complete..."); 
       m_ClientSocket.shutdownOutput(); 

サーバ側でDOMを読み取るコードである:

​​

適用署名前DOMは、(署名が適用される前に、データが暗号化されている)次のようである:

<?xml version="1.0" encoding="UTF-8"?><SmMessageSet xmlns="urn:ccsds:recommendation:service_management:schema:sccs:R1.0" xmlns:ns2="urn:ccsds:recommendation:navigation:schema:ndmxml:R1.5"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Content"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/><xenc:CipherData><xenc:CipherValue>VosyFTcuAkzo6WPPLnnM2Nka+gpyD9r2cNy3fbSX8RjGg5dKktK9SGZAar5t3ci2mU6Nw9Ski2Td 
g1WNei+kgns6vFET5Ff8m5/VIO24sBz30DPO5cAwfLax0slTjZWDRu7XXs/ORSK2PrB8B8qaO+me 
W5iPLXjkkL4LnLwZfIvCSdG3JJoOTUhR6CstquTejRBLvTdvry8jB2RncjpV244eng7Bmk7HWcNd 
Mz20DujfX14MTyKAQcVAgUhM9MpisveiDRdKYtXWCkma2NcUhpxqzjyPtyJtHVJQfaPZ2kla2NQV 
DcMPUvmM+V0Y3kI5NBZq1vlIAg1i5JsZRniB+Q==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>8UCDr2ZzDvD5JczkPU7UnxRYBdxs6ZgL5s2ksHyn/FZvBVSwYh6o/Rnx41fnN6uygcylW++zoxSq 
a9qcpuS8rFxtw6TtRzZeixJYBgZWVHp9NYiB4WbtZF6iR5EjaGKZdghUgCVtvKKbpbMQTTPRCBym 
7HA2iQzNpGH1tcGegDB8+w3ALDP8QN5q3PG2uFBk880KXRozxAxKZVNKZfEZyat0fnzf6J8bTCac 
n1lxV02jCWyz1/2Gd/jfo8B2BLXVMZWm0WiM7Z/uk4PFsTQjPmb1CD+E+7Oh8TRJzIqC1dyPQVV+ 
kgdoJbM/2sZka1VCuUzEIEQ1fhH+iUE0ymtuw+djwhfqDAow1pfRJOsak2cXzLoYO7mwqmIHoeaM 
hN9IAtI/TfXDHNSL8ledhYT/ZL2gmNSR1Jze6JZPaXgqkmBEGVgqbzLex/5drxOf/DQVcugSnqEw 
uHrikLsjU4jHozNg4PGidJNPCKLPgJaiLX1rgyo9N6pUDMVrNH+Tz1G7EFydzZOrZt+yY8Je17NL 
ah8mBQb/S5zGD7642aDR4UmVQthD3LTMIG/oxbzMIh/OOcC432SZ+ShAvUD+bU+GDDdcOKzemLPB 
EV6QLstFqonyHLSTQqgIMU5z2NxFpJIKRBClX09q5fOytaRVrGIZgJtOfuT4zFwjmwF66yuiQp0H 
gD9O95A+ifmwe8k9KUsAO9Q8alxrXrqhptfsySCYDo2nSXbhSn5cKgsdK4jw5B6zsoQQZxJmzsYT 
ZSbo0DhjAbZVszsU0HeTMRKRNlOABXAJPxSmqz2hT/wgYnWSMZt839swJyOZhaMuOUfShAP1iVo+ 
m5xM+zw7SnsAwFozNw==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></SmMessageSet> 

XMLは、applySignatureの後とSignedInfoがverifysignatureメソッド内で変更された後は同じです。この問題は、ソケットを介してドキュメントを送信すると、SignedInfoの参照アイテムにあるように見えます。何らかの形で検証中に発生する変換は、チェックを失敗させる46バイトを追加しています。

どこから来たのかわからない。誰にでもアイデアはありますか?

答えて

0

これはエラーに直接関係していませんが、後でエラーが発生します.SignedInfo要素内のものを削除したり変更したりすることはできません。最終的な署名値は、正規化されたSignedInfo要素のダイジェストに対して計算されます。ですから、署名を検証する前に何か変更してしまえば、間違いなくそれを破ることになります。

あなたの文書ダイジェストがなぜ無効であるかに関しては、これは複数の理由があり、ちょうど推測から分析するのが難しいかもしれません。あなたが署名されていない文書をここに投稿できるなら、少なくとも正しいダイジェスト値が何であるかを教えてくれるでしょう...

+0

お返事ありがとうございます。このコードはSignedInfoの属性を削除しています。これは、ドキュメントをクライアント側のapplysignatureから出力されたものと同じに見せようとしていたためです。ソケット上でデータを送信するためにdomで実行していた変換が、追加の属性を追加した可能性があると私は考えていました。 –

0

問題はSignedInfoではなくKeyInfoノードで問題でした。 KeyInfoノードには、元の署名が適用されたときには存在しなかった名前空間属性が追加されていました。署名値をチェックする前にKeyInfo属性を削除すると、私が見ていた問題が修正されます。

0

短い答え:元の質問では、の先頭にdoc.normalizeDocument();を追加してください。署名を追加する前に。

詳細:

私は、これは古い質問ですけど、私は答えのいずれかによって解決されなかった同様の問題がありました。 実際、私は答えの一つが間違っていると思います、それは問題が検証にあると言います。しかし、私はそれが署名にあると信じています!私の経験と解決方法をここに置くことで、同様の問題を抱えている人に役立つことを願っています

私はXML文書を生成してから署名していました。私は両方のApache Santuarioと署名しようとしました。それがうまくいかなかったら、私はjavax.xml.crypto.dsigに切り替えました。

これらのメソッドは両方とも、Santuarioと外部ツールを使用してチェックしたときに正しく署名されていないXMLドキュメントを生成しました。まず

私は生成しようとした署名済みXMLの例:

<signed-envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="somenamespace" xsi:schemaLocation="someshemelocation"> 
    <object xml:id="object0"> 
     ... 
    </object> 
    <signatures> 
     <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
     ... 
     <SignedInfo> 
      <Reference URI="#object0"> 
      ... 
     </SignedInfo> 
     </Signature> 
    </signatures> 
</signed-envelope> 

​​の名前空間が重要です!すべてが名前空間なしで完全に機能しました。しかし、必要な名前空間を​​に追加すると、署名が検証できなかったXMLファイルが生成されました。また、外部ツールではない(これは、署名が失敗したことを意味し、検証ではありません)!

Santuarioはlog4jを使用して大きなデバッグ出力を提供します。検証途中、次の名前空間が<object><SignedInfo>の両方に追加されました:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

これは検証するための正しい方法であるこの出力は、WHがあることを示しました!ここの答えの1つは、それが正しいとは言えず、それを修正しようとしていますが、実際は正しいです。ここでの問題は、検証ではなく、署名することです!

Santuarioは、この名前空間が文書に署名するときに追加されなかったことを示しています。これは、私が生成したDocumentオブジェクトで何かが間違っていたと私に信じさせました。 私のXML文書が次のようにルート要素に追加された名前空間で生成されました:

rootElement.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "xsi:noNamespaceSchemaLocation", "some_namespace"); 

を検索多くの後、私はdoc.normalizeDocument()は、同様の問題を解決していることが分かりました。私はそれを試して、すべての作品!
なぜdoc.normalizeDocument()がすべて動作するのか分かりませんが、Apache Santuarioとjavax.xml.crypto.dsigの両方で正しく署名できます。だから両方が正しく署名するためにこれが必要です。

関連する問題