Frage

kann ich erfolgreich manuelle Referenzvalidierung (canonicalize jeden referenzierte Element -> SHA1 -> Base64 -> prüfen, ob es das gleiche von Digest Inhalt ist) aber ich kann nicht mit der Überprüfung der SignatureValue. Hier ist die SignedInfo zu canonicalize 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 alle Räume zwischen den Tags (und so immer das gesamte Element auf einer einzigen Zeile) zu entfernen, habe ich diese SHA1 (in Base64) verdauen erhalten:

6l26iBH7il / yrCQW6eEfv / VqAVo =

Jetzt erwarte ich nach der Entschlüsselung des SignatureValue Inhalts das gleiche verdauen zu finden, aber ich bekomme eine differente und mehr Wert:

MCEwCQYFKw4DAhoFAAQU3M24VwKG02yUu6jlEH + u6R4N8Ig =

Hier ist ein 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 ich verwirrt viel ist, dass die beiden Digests unterschiedliche Größe haben, aber natürlich habe ich auch genau den gleichen Wert aus den beiden Berechnungen erhalten muß. Irgendwelche Vorschläge? Danke.

War es hilfreich?

Lösung

MCEwCQYFKw4DAhoFAAQU3M24VwKG02yUu6jlEH+u6R4N8Ig= ist Base64-Kodierung für eine DIE-codierte ASN.1 Struktur: a SEQUENCE zuerst eine AlgorithmIdentifier enthält (in dem es heißt, dass dies SHA-1, ohne Parameter, da SHA-1 akzeptiere keine), dann wird ein OCTET STRING welches enthält die Sind 20-Byte-Wert. In hexadezimal ist der Wert: dccdb8570286d36c94bba8e5107faee91e0df088

.

Diese ASN.1 Struktur ist Teil der Standard RSA-Signatur Mechanismus. Sie verwenden RSA Entschlüsselung , um den Zugang, dass Struktur, die Nicht-Standard ist. Sie sind wirklich glücklich überhaupt etwas zu bekommen, da RSA-Verschlüsselung und RSA-Signatur sind zwei verschiedene Algorithmen. Nun ist es so, dass sie beide Futter auf die gleiche Art von Schlüsselpaaren, und dass die „alten Stil“ (aka „PKCS # 1 v1.5“) Signatur- und Verschlüsselungssysteme verwenden ähnliche Polstertechniken (ähnlich, aber nicht identisch, es ist schon ein wenig überraschend, dass die Java-Implementierung von RSA nicht über die Unterzeichnung padding Drossel hat, wenn bei der Entschlüsselung Modus verwendet wird).

Wie auch immer, 6l26iBH7il/yrCQW6eEfv/VqAVo= ist Base64-Codierung für einen 20-Byte-Wert, der in Hexadezimal ist: ea5dba8811fb8a5ff2ac2416e9e11fbff56a015a. Dies ist, was Sie erhalten, indem die XML-Struktur Hashing Sie oben zeigen, nachdem alle Leerzeichen zwischen Tags entfernt zu haben. Entfernen alle Leerzeichen ist nicht richtige Kanonisierung. Eigentlich, so weit ich weiß, Leerzeichen nur zwischen Attributen beeinflusst wird, innerhalb der Tags, aber externe Leerzeichen müssen unverändert gehalten werden (mit Ausnahme der Zeilenende Normalisierung [die LF / CR + LF Sache]).

Der Wert, der für die Erzeugung der Signatur verwendet wurde (die dccdb85...) kann unter Verwendung des XML-Objekts erhalten werden Sie zeigen, und durch die führenden Leerzeichen entfernt werden. Um klar zu sein: Sie kopieren + die XML in eine Datei einfügen, dann entfernen Sie die führenden Leerzeichen (0 bis 3 Leerzeichen) pro Zeile. Sie stellen sicher, dass alle End-of-Linien verwenden, um ein einzelnes LF (0x0A Byte) und Sie den letzten LF entfernen (die man nur nach </ds:SignedInfo>). Die sich ergebende Datei muss Länge 930 Byte haben, und ihre SHA-1-Hash ist der erwartete Wert dccdb85....

Andere Tipps

Ein Blick auf Ihren speziellen XML-Token, das kann ich Ihnen sagen, ein paar Dinge.

  • Sie haben die Kanonisierung Methode Exclusive XML Kanonisierung Version 1.0 . Dies ist ein sehr Wichtig Faktor um sicherzustellen, dass Sie die richtige Digest-Werte und Unterschrift.

  • produzieren
  • Sie verwenden die gleiche Kanonisierung Methode sowohl für die Referenz Verdauansätzen Berechnung und für Kanonisierung des SignedInfo bevor die Unterschrift zu erzeugen.

Die Spezifikation für Exclusive XML Canonicalizaiton Version 1.0 wird von W3C produziert und kann an seinem jeweiligen mein Blog . Es beschreibt den Prozess sehr viel ausführlicher als meine Antwort, da es viele Feinheiten zu XML Signature sind. Es enthält auch Links zu vorherrschenden Spezifikationen und RFCs.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top