Manuelle überprüfung der XML-Signatur
Kann ich erfolgreich manuell referenzbestätigung (kanonisieren jedes referenzierte element --> SHA1 --> Base64 --> überprüfen, ob es die gleiche von DigestValue Inhalt), aber ich scheitere mit der überprüfung der SignatureValue. Hier ist die SignedInfo zu kanonisieren und hash:
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#element-1-1291739860070-11803898">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>d2cIarD4atw3HFADamfO9YTKkKs=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#timestamp">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>YR/fZlwJdw+KbyP24UYiyDv8/Dc=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
Ater entfernen Sie alle Leerzeichen zwischen den tags (und damit immer das gesamte element auf einer einzigen Zeile), habe ich dies erhalten sha1-digest (Base64):
6l26iBH7il/yrCQW6eEfv/VqAVo=
Nun erwarte ich zu finden, die den gleichen digest-nach der Entschlüsselung des SignatureValue Inhalt, aber ich bekomme eine differente und mehr Wert:
MCEwCQYFKw4DAhoFAAQU3M24VwKG02yUu6jleh+u6R4N8Ig=
Hier einige java-code für die decyption:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new File(inputFilePath));
NodeList nl = doc.getElementsByTagName("ds:SignatureValue");
if (nl.getLength() == 0) {
throw new Exception("Cannot find SignatureValue element");
}
String signature = "OZg96GMrGh0cEwbpHwv3KDhFtFcnzPxbwp9Xv0pgw8Mr9+NIjRlg/G1OyIZ3SdcOYqqzF4/TVLDi5VclwnjBAFl3SEdkyUbbjXVAGkSsxPQcC4un9UYcecESETlAgV8UrHV3zTrjAWQvDg/YBKveoH90FIhfAthslqeFu3h9U20=";
X509Certificate cert = X509Certificate.getInstance(new FileInputStream(<a file path>));
PublicKey pubkey = cert.getPublicKey();
Cipher cipher = Cipher.getInstance("RSA","SunJCE");
cipher.init(Cipher.DECRYPT_MODE, pubkey);
byte[] decodedSignature = Base64Coder.decode(signature);
cipher.update(decodedSignature);
byte[] sha1 = cipher.doFinal();
System.out.println(Base64Coder.encode(sha1));
Die Sache, die mich verwirrt viel ist, dass die zwei digests haben unterschiedliche Größe, aber natürlich habe ich auch erhalten müssen genau den gleichen Wert aus beiden Berechnungen angezeigt. Irgendwelche Vorschläge? Danke.
- "Ater entfernen Sie alle Leerzeichen zwischen den tags"... ist das richtig? Suche auf w3.org/TR/2001/... es klingt wie Sie vielleicht zu entfernen zu viel whitespace.
- Danke für die Antwort. Ich verstehe deinen Punkt, aber,wie gesagt, am Anfang die Frage, kann ich das erfolgreich tun referenzbestätigung (zwei Referenzen, es kann nicht sein, ein Unfall) die gleichen SOAP-Nachricht und nur durch entfernen die Leerzeichen, so muss ich davon ausgehen, dass es stimmt.
- Die Heiligsprechung ist viel mehr als das entfernen von whitespace-Zeichen. Es behandelt das namespace-Präfix Fragen, Attributreihenfolge, und im Allgemeinen alles, das ändert die byte-Reihenfolge der phisicaly-Datei (und somit die hash-digest), ändert aber nicht die XML-infoset (== die Bedeutung, die Nutzdaten der XML)
- Natürlich. Ich benutze org.apache.xml.Sicherheit.c14n.Canonicalizer aber nachdem ich müssen, entfernen Sie Leerzeichen, um die gleiche verdaut, von denen in der xml.
- Ok habe ich gefunden, warum das digest der Entschlüsselung ist also groß: es besteht aus Präfix+tatsächliche digest (w3.org/TR/2002/REC-xmldsig-core-20020212/Overview.html). Aktuelle digest ist in den letzten 20 bytes. Jetzt habe ich zwei gleich große verdaut, aber immer noch unterschiedlich sind, hat jedes andere 🙁
Du musst angemeldet sein, um einen Kommentar abzugeben.
MCEwCQYFKw4DAhoFAAQU3M24VwKG02yUu6jlEH+u6R4N8Ig=
ist die Base64-Codierung für eines DER-kodierten ASN.1-Struktur: einSEQUENCE
enthält zunächst eineAlgorithmIdentifier
(die besagt, dass dies ist SHA-1, ohne Parameter, da SHA-1 akzeptiert keine), dann einOCTET STRING
welcher die aktuelle 20-byte-Wert. In hexadezimal den Wert:dccdb8570286d36c94bba8e5107faee91e0df088
.Diese ASN.1-Struktur ist Teil der standard - RSA-Signatur Mechanismus. Sie sind mit RSA Entschlüsselung Zugriff auf die Struktur, die nicht dem standard entsprechen. Sie sind eigentlich glücklich, Sie bekommen zu überhaupt nichts, da RSA-Verschlüsselung und RSA-Signatur sind zwei unterschiedliche algorithmen. So kommt es, dass Sie beide Füße auf die gleiche Art von Schlüssel-Paaren, und dass die "old-style" (aka "PKCS#1 v1.5") Signatur-und Verschlüsselungsverfahren verwenden, ähnlich Polsterung Techniken (ähnlich, aber nicht identisch; es ist schon ein bisschen verwunderlich, dass die Java-Implementierung von RSA nicht ersticken auf die Signatur Polsterung eingesetzt bei der Entschlüsselung Modus).
Jedenfalls
6l26iBH7il/yrCQW6eEfv/VqAVo=
ist die Base64-Codierung für eine 20-byte-Wert, der, in hexadezimal ist:ea5dba8811fb8a5ff2ac2416e9e11fbff56a015a
. Dies ist, was Sie erhalten, die von der Vermischung der XML-Struktur, die Sie oben zeigen, nachdem entfernt alle Leerzeichen zwischen den tags. Entfernen Sie alle whitespace-Zeichen nicht richtige Kanonisierung. Eigentlich, soweit ich weiß, whitespace ist betroffen, nur zwischen Attributen innerhalb der tags, aber auch externe whitespace-Zeichen müssen unverändert beibehalten werden (außer Zeilenende Normalisierung [LF /CR+LF Ding]).Den Wert, der verwendet wurde für die signature generation (die
dccdb85...
) kann abgerufen werden, mithilfe der XML-Objekt, das Sie zeigen, und entfernen Sie die führenden Leerzeichen. Um klar zu sein: Sie kopieren+einfügen der XML-Daten in eine Datei, dann entfernen Sie die führenden Leerzeichen (0-3 Leerzeichen) pro Zeile. Stellen Sie sicher, dass alle end-of-lines verwenden Sie ein einzelnes LF (0x0A byte), und entfernen Sie das Letzte LF (die man nur nach</ds:SignedInfo>
). Die resultierende Datei muss Länge 930 bytes, und seine SHA-1 hash der zu erwartendendccdb85...
Wert.Blick auf Ihre speziellen XML-token, ich kann Ihnen sagen, ein paar Dinge.
Sind Sie mit der Kanonisierung Methode Exclusive XML
Canonicalization Version 1.0. Dies ist ein sehr WICHTIG Faktor
um sicherzustellen, dass Sie produzieren die richtige digest-Werte und Unterschrift.
Sind Sie mit der gleichen Kanonisierung Methode zur Berechnung der Referenz verdaut, und für canonicalizing die SignedInfo
vor dem erzeugen der Signatur.
Die Spezifikation für Exklusive XML-Canonicalizaiton Version 1.0 ist produziert von W3C und kann gefunden werden an seinem jeweiligen W3C-Empfehlung. Wenn Sie berechnen Sie Ihre Werte manuell ein, werden Sie sicher, dass Sie konform sind exakt auf die Spezifikation, weil die Kanonisierung ist eine harte Sache zu Recht erhalten, und ist sehr wichtig, diese richtig zu tun, sonst werden Ihre Werte falsch sein.
Schrieb ich einen ausführlichen Artikel zu beschreiben die XML-Signatur-Validierung. Der Artikel befindet sich bei mein blog. Es beschreibt den Prozess sehr viel Ausführlicher als meine Antwort, denn es gibt viele Feinheiten, um XML-Signatur. Es enthält auch links zu gängigen Spezifikationen und RFCs.