MD5 encryption question - communication with Java

A

AHanso

Hey I am new to C# (My background is in Java),

I am writing a C# application (that uses the Compact Framework) that
communicates to a Java server. To login the server is expecting the
password to be MD5 encrypted, and then base64 encoded. The Java client
is doing this as follows, and it works with the server:

private static String encodePassword(String password) {

try {
MessageDigestalgorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(password.getBytes());
byte[] encrypted = algorithm.digest();

ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStream encoder = MimeUtility.encode(out, "base64");
encoder.write(encrypted);
return new String(out.toByteArray());

} catch (...exception code )
}
}

This returns a value of: ISMvKXpXpadDiUoOSoAf

In c# when I try to do this I get a very different value, The current
code is doing this...

System.Security.Cryptography.MD5 md5 =
System.Security.Cryptography.MD5.Create ();
byte[] encrypted =
md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(password));
string encoded = Convert.ToBase64String(encrypted, 0,
encrypted.Length);

This returns a value of: ISMvKXpXpadDiUoOSoAfww==

My questions are what would be causing the difference between the Java
output and the c# output? The Java server is expecting the first
value.

What is the proper way to do this?

And last, where is the best place to learn about this? I have been
doing a lot of looking on line, but wondering what the best site would
be to learn about some of these issues. (I will have the same problem
looking for XML handeling in C# too)

Thank you for your help. Other than these problems I have been pretty
shocked at how easy the conversion to C# has been. Kind of fun.
 
L

Larry Lard

AHanso said:
Hey I am new to C# (My background is in Java),

I am writing a C# application (that uses the Compact Framework) that
communicates to a Java server. To login the server is expecting the
password to be MD5 encrypted
Hashed.

, and then base64 encoded. The Java client
is doing this as follows, and it works with the server:

private static String encodePassword(String password) {

try {
MessageDigestalgorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(password.getBytes());
byte[] encrypted = algorithm.digest();

ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStream encoder = MimeUtility.encode(out, "base64");
encoder.write(encrypted);
return new String(out.toByteArray());

} catch (...exception code )
}
}

This returns a value of: ISMvKXpXpadDiUoOSoAf

Might help if you told us what the password is... or rather, some other
random string, and the results of encoding it in Java and C#.
In c# when I try to do this I get a very different value

Not that different! :)
, The current
code is doing this...

System.Security.Cryptography.MD5 md5 =
System.Security.Cryptography.MD5.Create ();
byte[] encrypted =
md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(password));
string encoded = Convert.ToBase64String(encrypted, 0,
encrypted.Length);

This returns a value of: ISMvKXpXpadDiUoOSoAfww==

OK so the Java gives us

ISMvKXpXpadDiUoOSoAf

and the C# gives us

ISMvKXpXpadDiUoOSoAfww==

Since base64 encoding turns arbitary 3-byte sequences into printable
4-byte sequences, we can see that the C# output is the result of base64
encoding the same input, with an extra three bytes on the end. However,
we also know that = is the base64 padding character, so there will be
fewer than three bytes extra. We can find out exactly what the extra is
by asking the Immediate window:

?Convert.FromBase64String("fw==")
{Dimensions:[1]}
[0]: 127

Aha. So the input to the base64 encoding is carrying an extra byte
(value 127) on the end, compared to the Java. The Java base64 string is
the encoding of 15 bytes, and the C# base64 is the encoding of 16
bytes.

At this point I wondered which is correct. The .NET MD5 class is
inherited from HashAlgorithm, which specified a HashSize member, which
for MD5 is 128 (bits) = 16 bytes. Checking the definition of MD5
(wikipedia), I see that an MD5 hash is indeed supposed to be 128 bits =
16 bytes. But you say that passing ISMvKXpXpadDiUoOSoAf is currently
giving the correct result? Well, ISMvKXpXpadDiUoOSoAf is the base64
encoding of only 15 bytes! Which makes for something of a mystery, and
smells like a bug *somewhere*.

However, let's not worry about that right now, let's rather just change
the C# from

string encoded = Convert.ToBase64String(encrypted, 0,
encrypted.Length);

to

string encoded = Convert.ToBase64String(encrypted, 0, 15);

and see if it works. If it works, go pester whoever's responsible for
the Java server. If not... come back here! :)

And last, where is the best place to learn about this? I have been
doing a lot of looking on line, but wondering what the best site would
be to learn about some of these issues. (I will have the same problem
looking for XML handeling in C# too)

I usually start with a book for the basics, for more in depth stuff on
the technical side I wuold go to wikipedia, for implementation details
I would search in this group.
Thank you for your help. Other than these problems I have been pretty
shocked at how easy the conversion to C# has been. Kind of fun.

Well, less surprising when you consider the history and motivations
behind C# ...
 
A

AHanso

Thank you for the help. Sure enough using only 15 bytes worked. Of
course the fun part of solving this problem is that I now have another
task added to my list. I now also get to go back and figure out what
is happening on the server and fix that too.
 
J

Jon Skeet [C# MVP]

AHanso said:
Thank you for the help. Sure enough using only 15 bytes worked. Of
course the fun part of solving this problem is that I now have another
task added to my list. I now also get to go back and figure out what
is happening on the server and fix that too.

Try closing the encoder - it's no doubt waiting for you to write some
more binary data to it so it can produce the next chunk of base64.
(I suspect there are nicer ways of converting to base64, by the way.
Have a look at the Apache Codec classes. IIRC, they've got some base64
abilities.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top