MessageDigges md5 differs from the database md5 string - java

MessageDigest md = MessageDigest.getInstance("MD5");
String md5password = new String(md.digest("test".getBytes("UTF-8")), "UTF-8");
I have the same string "test" in my database, but here I get something different like this:
�k�F!�s��N�&'��
database:
098f6bcd4621d373cade4e832627b4f6

This is the problem:
new String(md.digest("test".getBytes("UTF-8")), "UTF-8");
You're trying to decode the result of the MD5 digest as if it were a UTF-8 string. It's not. It's not text at all - it's just binary data. What you're doing is like trying to load an image or music file as a string - it's just a bad idea.
It looks like your database is either storing it as binary data and showing you a hex representation, or storing it as hex. I suggest you do the same. There are lots of Stack Overflow questions about converting byte arrays to hex in Java, so that part should be simple.

Related

Java Multipart file to blob then back to Image has loads of random characters

I am recieveing an image from a jsp, converting into a byte, then blob and saving it in my Database, on a different page I am then retriving it, and when I retrieve the image I get the following String.
'x*??{[?Y?>YE *?????_/???????~%?+y?`??uH????#??\t?????|B??k?-??Z4V?U7?F???m+(?? ? I??pq^?Q???????18?R???-???>0~?sXxCI?;[;t???9?fBX?Bp?A??^M?k? ??G?S?u???????r?U&‚w*??8????`??> Y?2?????1?j$??\??DR[??t0? pps?_Ex? ???_o?*?? xV)?6D8?$??!?9??~???N?`???}W?s?gNUf?Mn>?s?3?r?3M???X???Q????N!pr~?W????Mjq5??????2m???8????x??V?????????[???"??*,I?/#s?V?d?B?/?Vb?&R?n|?>??2????)?r??1??%7?Q??^f?R?C?????mvm??%6?K?p??;O?Z?&?????u?????\???R"ZOex???VkE???????_??????K?M#=??o?Z[?[hb?H?V????
I have cut this down manually on here.
This is the tag that I have done.
<img src="data:image/jpeg;base64,${img}" width="100" height="100"></img>
I'm not quite sure what has gone wrong here, here is where I have taken the file and made it into a byte[] then a blob.
byte[] byteData = file.getBytes();
Blob blobs = new SerialBlob(byteData);
and how then I've converted it into a base64 string.
String base64DataString = new String(byteData , "UTF-8");
System.out.println(base64DataString);
model.addAttribute("img", base64DataString);
If anyone has any idea how I can turn this string into a normal base64 string which can be used to reproduce an image, that would be very helpful.
Jim
String base64DataString = Base64.getEncoder().encodeToString(byteData);
Binary data should never be converted to String, which contains Unicode, mostly as UTF-16 chars, where every byte costs 2 bytes (one char), and the conversion takes time and probably goes wrong.

How to get the same MD5 string in Java as in C#

I have code in C# which produces MD5 encoded byte[] from String and then this byte[] is converted to String. The C# code is
byte[] valueBytes = (new UnicodeEncoding()).GetBytes(value);
byte[] newHash = (new MD5CryptoServiceProvider()).ComputeHash(valueBytes);
I need to get the same result in Java. I'm trying to do this
Charset utf16 = Charset.forName("UTF-16");
return new String(DigestUtils.md5(value.getBytes(utf16)), utf16);
The code is using Apache Commons Codec library for MD5 calculations. I'm using UTF16 charset because I've read in other SO questions that C#'s UnicodeEncoding uses it by default.
So the code snippets look like they do the same thing, but when I'm passing the string byndyusoft2014, C# gives me hV7u6mQYRgBXXF9jOWWYJg== and Java gives me ﹡둛뭶魙ꇥ늺ꢑ. I've tried UTF16LE and UTF16BE as charsets with no luck.
Has anyone idea about what I'm doing wrong?
I think because of the java decode string to byte[] with utf-8,but the C# is not.So the java and C# encode the different byte array,and then get the different result.You can decode the string to byte[] at c# with utf-8,and see the result.Like following code:
UTF8Encoding utf8 = new UTF8Encoding();
byte[] bytes=utf8.GetBytes("byndyusoft2014");
byte[] en=(new MD5CryptoServiceProvider()).ComputeHash(bytes);
Console.WriteLine(Convert.ToBase64String(en));
and the java code:
byte[] en = DigestUtils.md5Digest("byndyusoft2014".getBytes());
byte[] base64 = Base64Utils.encode(en);
System.out.println(new String(base64));
Of course,in your description,the result of C# like be encoded with base64,so the java should encode the byte array with base64.
The result of them is same as swPvmbGDI1GbPKQwL9knjQ==
The DigestUtils and Base64Utils is some implementation of MD5 and BAS64 in spring library
As it turned out, the main difference was not presented in my original code snippet - it was convertation from MD5 encoded byte[] to String. You need to use Base64 to get final result. This is the working code snippet in Java
Charset utf16 = Charset.forName("UTF-16LE");
return new String(Base64.encodeBase64(DigestUtils.md5(value.getBytes(utf16))));
With this code I get the same result as with C#. Thank you all for good hints!

Hashing a password in java and trying to convert in string

I actually have a problem with hashing a password and trying to convert in string to put it in a database.
Currently I have this code
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(motsDePasse.getBytes(StandardCharsets.UTF_8));
String fileString = Base64.getEncoder().encodeToString(hash);
The deal is that it does not give me the good hash. Let's say I try to hash "12345". It should give me 5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5.
But it actually return WZRHGrsBESr8wYFZ9sx0tPURuZgG2lmzyvWpwXPKz8U=
try using a hex encoder
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest("12345".getBytes(StandardCharsets.UTF_8));
String hex = DatatypeConverter.printHexBinary(hash);
System.out.println(hex);
output
5994471ABB01112AFCC18159F6CC74B4F511B99806DA59B3CAF5A9C173CACFC5
You are Base64 encoding it. If you Hex encode it, you will get the output you are looking for.
You're encoding your bytes in base 64. If you want to encode it in hexadecimal, try here: Java code To convert byte to Hexadecimal. If you're putting into a database as a string though, base64 should be fine for your needs.

What is the correct format for the API SurveyQuestionImage.Data field?

I am working with the GCS API, attempting to create a survey with image data.
I am using the NuGet package Google.Apis.ConsumerSurveys.v2 version 1.14.0.564 on the .Net platform. I can create surveys that do not contain image data without problem. However, when I try to create a survey with image data I receive an error from the API.
I have on hand base64 encoded png format image data. My images display properly in an IMG tag on a web page when the src attribute is set to
'data:image/png;base64,<image base64 string>'
I want to send this image data to the API to populate the survey image. My understanding is that I need to set the Data property of the Google.Apis.ConsumerSurveys.v2.Data.SurveyQuestionImage object to a string containing the image data. I have not been successful.
I first decode my base64 string to a byte array:
byte[] bytes = Convert.FromBase64String(<image base64 string>);
I have tried setting the Data property in the SurveyQuestionImage object as:
image.Data = Encoding.Unicode.GetString(bytes);
This results in this error from the API:
Google.Apis.Requests.RequestError Invalid value for ByteString: <the Data string>
I have also tried converting the byte array to a hexadecimal encoded string as:
StringBuilder sb = new StringBuilder(bytes.Length);
foreach (Byte b in bytes)
{
sb.Append(b.ToString("X2"));
}
image.Data = sb.ToString();
This results in the more hopeful error:
Google.Apis.Requests.RequestError Invalid Value supplied to API: image_data was bad. Request Id: 579665c300ff05e6c316a09e600001737e3430322d747269616c320001707573682d30372d32322d72313000010112 [400] Errors [ Message[Invalid Value supplied to API: image_data was bad. Request Id: 579665c300ff05e6c316a09e600001737e3430322d747269616c320001707573682d30372d32322d72313000010112] Location[ - ] Reason[INVALID_VALUE] Domain[global] ]
Does anyone know the correct format for the Data property of the Google.Apis.ConsumerSurveys.v2.Data.SurveyQuestionImage object?
The data needs to be base64 encoded and also "urlsafe" or "websafe" depending on what language you are using. (python and java, respectively)
In other words, you'll need to first base64 encode then:
Web safe encoding uses '-' instead of '+', '_' instead of '/'
Hope this helps!
For c# users, check out this technique for making websafe b64:
How to achieve Base64 URL safe encoding in C#?
For .net users, look at the comments in this question:
Converting string to web-safe Base64 format
And also this link for more info about .net specific options for encoding:
http://www.codeproject.com/Tips/76650/Base-base-url-base-url-and-z-base-encoding
And to specifically answer the original poster, try this for converting your byte array to a string.
public static string ToBase64ForUrlString(byte[] input)
{
StringBuilder result = new StringBuilder(Convert.ToBase64String(input).TrimEnd('='));
result.Replace('+', '-');
result.Replace('/', '_');
return result.ToString();
}

NSData to Java String

I've been writing a Web Application recently that interacts with iPhones. The iPhone iphone will actually send information to the server in the form of a plist. So it's not uncommon to see something like...
<key>RandomData</key>
<data>UW31vrxbUTl07PaDRDEln3EWTLojFFmsm7YuRAscirI=</data>
Now I know this data is hashed/encrypted in some fashion. When I open up the plist with an editor (Property List Editor), it shows me a more "human readable" format. For example, the data above would be converted into something like...
<346df5da 3c5b5259 74ecf683 4431249f 711630ba 232c54ac 9bf2ee44 0r1c8ab2>
Any idea what the method of converting it is? Mainly I'm looking to get this into a Java String.
Thanks!
According to our friends at wikipedia, the <data> tag contains Base64 encoded data. So, use your favorite Java "Base64" class to decode (see also this question).
ps. technically, this is neither "hashed" nor "encrypted", simply "encoded". "Hashed" implies a one-way transformation where multiple input values can yield the same output value. "Encrypted" implies the need for a (usually secret) "key" to reverse the encryption. Base64 encoding is simply a way of representing arbitrary binary data using only printable characters.
After base64 decoding it you need to hex encode it. This is what PL Editor is showing you.
So...
<key>SomeData</key>
<data>UW31ejxbelle7PaeRAEen3EWMLojbFmsm7LuRAscirI=</data?
Can be represented with...
byte[] bytes = Base64.decode("UW31ejxbelle7PaeRAEen3EWMLojbFmsm7LuRAscirI=");
BigInteger bigInt = new BigInteger(bytes);
String hexString = bigInt.toString(16);
System.out.println(hexString);
To get...
<516df5aa 3c5b5259 74ecf683 4401259f 711630ba 236c59ac 9bb2ee44 0b1c8ab2>

Categories