2016-09-15 6 views
0

Ich habe eine einfache Frage. Ich brauche eine sha256 Prüfsumme Methode von Java nach C#Konvertieren von SHA256 von Java zu C#

So neu zu schreiben Ich habe diese Java Kabeljau mit arbeiten:

Canonicalizer c14Canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS); 
byte[] byteArray = c14Canonicalizer.canonicalizeSubtree(doc); 

// At this point, the byteArray in Java and the data in C# matches up. 
// That is, after the java bytes are converted to unsigned bytes using 
// java.lang.Byte.toUnsignedInt() 

MessageDigest md = MessageDigest.getInstance("SHA-256"); 
md.update(byteArray); 
byte byteData[] = md.digest(); 

(byteArray ist, Sie ahnen es, ein Byte-Array: D)

Von dem, was ich finden kann, sollte die update() - und digest() - Methode grundsätzlich die TransformerBlock() - und TransformFinalBlock() -Methoden in der jeweiligen HashAlgorithm abgeleiteten Klasse ersetzen (in diesem Fall SHA256).

Also das habe ich mit etwas versucht, ähnlich # in C:

var data = Encoding.UTF8.GetBytes(xmlString); 

// At this point, the byteArray in Java and the data in C# matches up. 
// That is, after the java bytes are converted to unsigned bytes using 
// java.lang.Byte.toUnsignedInt() 

using (var sha256 = SHA256.Create()) 
{ 
    byte[] shaBytes = new byte[data.Length]; 
    data.CopyTo(shaBytes, 0); 

    sha256.TransformBlock(shaBytes, 0, shaBytes.Length, shaBytes, 0); 

    sha256.TransformFinalBlock(shaBytes, 0, shaBytes.Length); 
    return sha256.Hash; 
} 

(und wieder Daten ist ein Byte-Array)

jedoch die Bytes bis nicht übereinstimmen. Fehle ich hier etwas?

(natürlich auch ich bin, sonst wäre es funktionieren, oder? S)

UPDATE

Sie einige weitere Informationen zu geben, weiter zu gehen, habe ich die Bytes abgestimmt zwischen Java und C# -Code, bevor Sie den Code ausführen, den Sie oben sehen. Und dann passen sie zusammen. Die Bytes im C# -Code stammen jedoch aus einer UTF8-codierten Zeichenfolge, während die Java-Bytes von einer c14Canonicalizer.canonicalizeSubtree() -Methode stammen.

Ich werde die obigen Codebeispiele aktualisieren, um ihre Ursprünge einzubeziehen.

UPDATE

Für was es wert ist, das Java md.digest() Methode gibt die folgende Bytes:

-86, 44, 95, 84, 3, 50, 7, -119 , -36, 46, 39, 32, -120, 7, 10, -86, -101, 110, -93, -72, -13, -93, -42, 111, 0, 59, -85, - 63, -15, -98, -17, -52

wenn umgewandelt, die zu

170,44,95,84,3,50,7,137,220,46,39,32,136,7,10,170,155,110,163,184 übersetzt, 243,163,214,111,0,59,171,193,241,158,239,204

während der C# -Code gibt

72,108,14,47,15,200,209,10,68,87,17,220,67,226,162,123,69,186,130,167,239,250,180,178,75,101,39,195,32,171,156,178

wenn sha256.ComputeHash() mit

+0

Bitte brach diese Frage: http://stackoverflow.com/questions/1521249/generating-an-xml-document-hash-in-c-sharp – mkysoft

+1

Was bedeutet ein unabhängiges Werkzeug (sprich: garantierten Arbeits) wie 'sha256sum' drucken? – rustyx

+0

@RustyX Ich habe versucht auf http://onlinemd5.com, und das Ergebnis ist gleich dem Ergebnis aus dem Java-Code. – Shazi

Antwort

0

Ich habe das Problem gefunden. Das Problem waren die Zeichen, die für Zeilenumbrüche in der XML-Zeichenfolge verwendet wurden. in meinem XML \ r \ n wird für Zeilenumbrüche verwendet, was getan werden musste, war, es in \ n zu ändern, was zu sein scheint, was Java verwendet.

fand ich die Antwort here wo Gerben Rampaart die gleiche Sache auf verschiedenen Online-sha256-Rechner und ken2k wusste, was der Unterschied

war bemerkt hatte Sobald ich, dass SHA256.TransformFinalBlock() arbeitete wie ein Charme getan hatte.

Die endgültige Lösung sieht ungefähr so ​​aus:

public byte[] GetDocumentHash(XmlDocument doc) 
{ 
    string formattedXml; 
    Transform canonicalTransform = new XmlDsigExcC14NWithCommentsTransform(); 
    canonicalTransform.LoadInput(doc); 

    using (Stream canonicalStream = (Stream)canonicalTransform.GetOutput(typeof(Stream))) 
    using (var stringWriter = new EncodingStringWriter(Encoding.UTF8)) 
    using (var xmlTextWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { NewLineChars = "\n", CloseOutput = false, Encoding = Encoding.UTF8, Indent = true, OmitXmlDeclaration = true })) 
    { 
     XmlDocument newDoc = new XmlDocument(); 
     newDoc.Load(canonicalStream); 
     newDoc.WriteTo(xmlTextWriter); 
     xmlTextWriter.Flush(); 
     formattedXml = stringWriter.GetStringBuilder().ToString(); 
    } 

    byte[] bytesToCalculate = Encoding.UTF8.GetBytes(formattedXml); 

    using (var sha256 = SHA256.Create()) 
    { 
     byte[] shaBytes = new byte[bytesToCalculate.Length]; 
     bytesToCalculate.CopyTo(shaBytes, 0); 

     sha256.TransformFinalBlock(shaBytes, 0, shaBytes.Length); 
     return sha256.Hash; 
    } 
} 

Es gibt wahrscheinlich viele Refactoring und Veredelung benötigt, aber es wird den Job zu erledigen.

Ein großes Dankeschön an alle, die mir geholfen haben!

0

Haben Sie die ComputeHash-Methode versucht?

heißt:

var byteArray = Encoding.ASCII.GetBytes("hello"); 
var sha = SHA256.Create(); 
byte[] outputBytes = sha.ComputeHash(byteArray); 
var result = BitConverter.ToString(outputBytes).Replace("-", "").ToLower(); 

EDIT

Können Sie das versuchen?

XmlDocument doc = new XmlDocument(); 
doc.LoadXml("xmlString"); 
XmlDsigExcC14NWithCommentsTransform c14n = new XmlDsigExcC14NWithCommentsTransform(); 
c14n.LoadInnerXml(doc.ChildNodes); 
Stream s = (Stream)c14n.GetOutput(typeof(Stream)); 
var sha = SHA256.Create(); 
byte[] outputBytes = sha.ComputeHash(s); 
+0

Ja, Sir, ich habe, vergeblich. – Shazi

+0

Können Sie das Ergebnis von md.digest() teilen; funktionieren? –

+1

@QuentinRoger Shazi Kalkulieren Hash für XML-Dokument mit ALGO_ID_C14N_EXCL_WITH_COMMENTS Algorithmus. Das kann man mit ComputeHash nicht berechnen. Wir müssen Kryptographie verwenden. Überprüfen Sie diese Frage: http://stackoverflow.com/questions/1521249/generating-an-xml-document-hash-in-c-sharp – mkysoft

0

Unter der Probe kann das gleiche Ergebnis geben. Weil Sie die gleiche Operation lange machen. In Ihrem Code erhalten Sie bereinigtes XML von XmlDsigExcC14NWithCommentsTransform und berechnen dann Hash. Im folgenden Beispiel berechnen Sie direkt.

XmlDocument doc = new XmlDocument(); 
doc.LoadXml("<a><xmlString>mkysoft</xmlString></a>"); 
XmlDsigExcC14NWithCommentsTransform c14n = new XmlDsigExcC14NWithCommentsTransform(); 
c14n.LoadInput(doc); 
var digest = c14n.GetDigestedOutput(SHA256.Create()); 
+0

Ich habe diesen Ansatz tatsächlich ausprobiert, aber er interpretiert immer noch neue Zeilen als \ r \ n, die einen anderen Digest ergeben, als wenn Sie ihn selbst ändern. Deshalb brauche ich das Xml, um den XmlWriter zu durchlaufen, bevor ich den Digest erhalte – Shazi