Converting SHA256 from Java to C#

强颜欢笑 提交于 2019-11-30 17:07:23

Did you try the ComputeHash method ?

i.e :

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

EDIT

Can you try this ?

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);
Shazi

I found the issue. The problem was the characters used for linebreaks in the xml-string. in my xml \r\n is used for linebreaks, what needed to be done was to change it to \n which seems to be what java uses.

I found the answer here where Gerben Rampaart had noticed the same thing on different online sha256-calculators and ken2k knew what the difference was

Once I had done that SHA256.TransformFinalBlock()worked like a charm.

The final solution looks something like this:

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

There's probably a lot of refactoring and refining needed, but it gets the job done.

A big thank you to all of you who helped me!

Below sample may be giving same result. Because you are making same operation long way. In your code, you are getting cleaned xml from XmlDsigExcC14NWithCommentsTransform then calculate hash. Below example calculate directly.

XmlDocument doc = new XmlDocument();
doc.LoadXml("<a><xmlString>mkysoft</xmlString></a>");
XmlDsigExcC14NWithCommentsTransform c14n = new XmlDsigExcC14NWithCommentsTransform();
c14n.LoadInput(doc);
var digest = c14n.GetDigestedOutput(SHA256.Create());
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!