2016-09-15 3 views
0

간단한 질문이 있습니다.SHA256을 Java에서 C로 변환 #

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, 당신은 그것을 짐작, 바이트 배열입니다 : D) 나는 C#

그래서

내가 작업이 자바 대구가 자바에서 SHA256 체크섬 방법을 다시 작성해야

update() 및 digest() 메서드는 기본적으로 각각의 HashAlgorithm 파생 클래스 (이 경우 SHA256)의 TransformBlock() 및 TransformFinalBlock() 메서드 대신 substitutet이어야합니다.

그래서 나는 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; 
} 

그러나, 바이트가 일치하지 않는 (다시, 데이터를 바이트의 배열입니다). 내가 여기서 뭔가를 놓치고 있니?

(물론 나는 물론, 그렇지 않으면 작동합니다 오른쪽 : S)

UPDATE 당신에 가서 좀 더 많은 정보를 제공하기 위해

, 나는 사이의 바이트 일치 한 위에서 본 코드를 실행하기 전에 Java 및 C# 코드를 사용하십시오. 그리고 나서 그들은 일치합니다. 그러나 C# 코드의 바이트는 UTF8 인코딩 문자열에서 가져오고 Java 바이트는 c14Canonicalizer.canonicalizeSubtree() 메소드에서 가져옵니다.

위의 코드 예제를 업데이트하여 해당 출처를 포함하도록하겠습니다.

UPDATE 그것은 가치가 무엇인지에 대한

, 자바 md.digest() 메소드는 다음 바이트 반환

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

1704495843507137220463932136710170155110,163,184로 변환하는 변환 243,163,214,111,059171193241158239204

sha256.ComputeHash()를 사용할 때 C# 코드는

72,10814471520020910688717220672261621236918613016723925018017875101,39,195,32,171,156,178

을 반환하면서

+0

이 질문을 경작하십시오 http://stackoverflow.com/questions/1521249/generating-an-xml-document-hash-in-c-sharp – mkysoft

+1

독립적 인 도구를 무엇을 (읽기 : 노동 보장) 'sha256sum' 프린트와 같은 것입니까? – rustyx

+0

@RustyX http://onlinemd5.com에서 시도한 결과는 Java 코드의 결과와 같습니다. – Shazi

답변

0

문제점을 발견했습니다. 문제는 xml-string에서 줄 바꿈에 사용 된 문자입니다. 내 xml \ r \ n에서 줄 바꿈에 사용되는 경우 수행해야 할 작업은 \ n을 Java에서 사용하는 것으로 보이는 \ n으로 변경하는 것입니다.

나는 가벤 Rampaart 다른 온라인 SHA256 - 계산기에 같은 일을 발견했다 대답 here을 발견하고 ken2k 내가 SHA256.TransformFinalBlock()이 마법처럼 일했다 행한 후에는 차이가

을 무엇인지 알고 있었다.

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; 
    } 
} 

아마 리팩토링 및 정제에 필요한 많은있다,하지만 작업이 완료 가져옵니다

최종 솔루션은 다음과 같은 형태.

큰 도움을 주신 모든 분들께 감사드립니다.

0

ComputeHash 메서드를 사용해 보셨습니까?

즉 :

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

편집

는 당신이 사용해 볼 수 있습니까?

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

예, 알겠습니다. – Shazi

+0

md.digest()의 결과를 공유 할 수 있습니까? 기능? –

+1

@QuentinRoger ALGO_ID_C14N_EXCL_WITH_COMMENTS 알고리즘을 사용하여 XML 문서의 Shazi 계산 해시. ComputeHash로 계산할 수 없습니다. 우리는 암호화를 사용해야합니다. 이 질문을 확인하십시오 : http://stackoverflow.com/questions/1521249/generating-an-xml-document-hash-in-c-sharp – mkysoft

0

아래 샘플은 동일한 결과를 제공 할 수 있습니다. 왜냐하면 당신은 먼 길을 똑같이 만들고 있기 때문입니다. 코드에서 XmlDsigExcC14NWithCommentsTransform에서 XML을 지우고 해시를 계산합니다. 아래 예제는 직접 계산합니다.

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

실제로 그 접근법을 시도했지만, 새로운 줄을 \ r \ n으로 해석하여 자신이 직접 \ n 변경하는 것보다 다른 다이제스트를 제공합니다. 따라서 XmlWriter를 통해 다이제스트를 가져 오기 전에 xml이 필요한 이유는 무엇입니까? – Shazi