Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different SHA1 Hash result between Java and C#

Tags:

java

c#

hash

sha1

I've a big problem. I using this C# function to encode my message:

byte[] buffer = Encoding.ASCII.GetBytes(file_or_text);
SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
String hashText = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");

On java side, I use this snippet:

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] sha1hash = new byte[40];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
sha1hash = md.digest();

My message is: Block|Notes|Text !£$%&/()=?^€><{}ç°§;:_-.,@#ùàòè+

I have this result:

(C#)   8EDC7F756BCECDB99B045FA3DEA2E36AA0BF0875
(Java) 2a566428826539365bb2fe2197da91395c2b1b72

Can you help me please?? Thanks...

like image 881
CeccoCQ Avatar asked Feb 27 '23 17:02

CeccoCQ


2 Answers

My guess is you seem to be comparing ASCII bytes to Latin1 bytes. Try switching

md.update(text.getBytes("iso-8859-1"), 0, text.length());

to this

md.update(text.getBytes("ISO646-US"), 0, text.length());

That might solve your problem.

(Or switch C# to use Latin1)

What is happening in your program your GetBytes method is returning different values for the same characters depending on encoding, so our nifty SHA1 hash algorithm is getting passed different parameters resulting in different return values.

like image 111
Meiscooldude Avatar answered Mar 01 '23 11:03

Meiscooldude


The change to use ISO-8859-1 on the C# side is easy:

byte[] buffer = Encoding.GetEncoding(28591).GetBytes(file_or_text);

However, both this and ASCII will lose data if your text contains Unicode characters above U+00FF.

Ideally if your source data is genuinely text, you should use an encoding which will cope with anything (e.g. UTF-8) and if your source data is actually binary, you shouldn't be going through text encoding at all.

like image 20
Jon Skeet Avatar answered Mar 01 '23 09:03

Jon Skeet