Enable Java sha1 raw mode like php sha1 - java

I get a problem with php.sha1 and my java code.
My php code
echo base64_encode(sha1("test", TRUE));
qUqP5cyxm6YcTAhz05Hph5gvu9M=
And my java code is:
static String Hash(String input) throws Exception {
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(input.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < result.length; i++) {
sb.append((result[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
}
return base64_encode(sb.toString());
}
output MTAxMDEwMDEwMTAwMTAxMDEwMDA=
How should I change the loop to get equal strings?

This one should works like RAW SHA-1
String base64 =
Base64.getEncoder().encodeToString(MessageDigest.
getInstance("SHA-1").digest(s.getBytes("ISO-8859-1")));

Related

MessageDigest in Java to C#

I am trying to translate java code to c#. I'm kind of stuck on this exercise below:
MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
md.update(pass.getBytes());
byte[] enc = md.digest();
StringBuilder hex = new StringBuilder();
for (int i = 0; i < enc.length; i++) {
String h = Integer.toHexString(0xFF & enc[i]);
hex.append((h.length() == 2) ? h : ("0" + h));
}
This is what I have tried but I am not getting the desired result which would be the following string: "e81e26d88d62aba9ab55b632f25f117d"
My Code:
using System.Security.Cryptography;
using System.Text;
string user_password = "HELLOWORLD";
byte[] hashBytes = Encoding.UTF8.GetBytes(user_password);
SHA1 sha1 = SHA1Managed.Create();
byte[] cryptPassword = sha1.ComputeHash(hashBytes);
user_password = Encoding.Default.GetString(cryptPassword);
StringBuilder hex = new StringBuilder();
for (int i = 0; i < cryptPassword.Length; i++)
{
// Store integer 182
int intValue = cryptPassword[i];
// Convert integer 182 as a hex in a string variable
string hexValue = intValue.ToString("X");
// Convert the hex string back to the number
int intAgain = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
hex.Append((intAgain.ToString().Length == 2) ? intAgain : ("0" + intAgain.ToString()));
}
Console.WriteLine("pass: " + hex.ToString());
Does anyone know the answer?
Main issue is you are using SHA1 function instead of MD5. Also Im not sure why you are looping over the password length. Every MD5 hash will be the same length regardless of input size.
using System;
using System.Security.Cryptography;
using System.Text;
string user_password = "HELLOWORLD";
byte[] hashBytes = Encoding.UTF8.GetBytes(user_password);
var md5 = MD5.Create();
var hash = md5.ComputeHash(hashBytes);
StringBuilder hex = new StringBuilder();
foreach (byte b in hash)
hex.AppendFormat("{0:x2}", b);
Console.WriteLine("pass: " + hex);
return ;

MD5 hash in android or java

I required to convert string in MD5 hash.
I am using
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex( byte[] bytes )
{
char[] hexChars = new char[ bytes.length * 2 ];
for( int j = 0; j < bytes.length; j++ )
{
int v = bytes[ j ] & 0xFF;
hexChars[ j * 2 ] = hexArray[ v >>> 4 ];
hexChars[ j * 2 + 1 ] = hexArray[ v & 0x0F ];
}
return new String( hexChars );
}
It is giving output like this website http://www.md5.cz/
but I required to generate hash as this http://webcodertools.com/hashstring giving output.
Please use test in both sites.
with using above function I am getting o/p like first site but I need as second site is giving.
Is there any different function or am I missing something in this?
Thanks.
The second web site is simply using base64 instead of hex to represent the binary data as text. So you can get rid of your bytesToHex method entirely, and just use Base64:
String base64Digest = Base64.encodeToString(thedigest, Base64.DEFAULT);
(As an aside, I'd avoid using the as a prefix in variable names - it provides no benefit, and is just cruft.)
Use this method it will return in the same format
public static String getMd5Hash(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
BigInteger number = new BigInteger(1, messageDigest);
String md5 = number.toString(16);
while (md5.length() < 32)
md5 = "0" + md5;
return md5;
} catch (NoSuchAlgorithmException e) {
Log.e("MD5", e.getLocalizedMessage());
return null;
}
}
This returns in //4a2028eceac5e1f4d252ea13c71ecec6 format MD5 of "WHAT" and
String base64format = Base64.encodeToString(thedigest, Base64.DEFAULT); //as given by #Jon Skeet
will return in the format as SiAo7OrF4fTSUuoTxx7Oxg==
Sorry for vice-versa solution.

Java equivalent of php pack('H*', str)

EDIT
I changed $checksum = md5($someString+$bkey); to $checksum = md5($someString.$bkey);
I need to perform the following operations in Java:
$hexString = '90aa';#sample value
$bkey = pack('H*',$hexString);
$someString='qwe';#sample value
$checksum = md5($someString.$bkey);
echo $checksum;
I can't convert hexString to bkey in Java to get the same result as php script. Except bkey everything is working properly.
If I remove bkey then:
PHP:
$someString='qwe';#sample value
$checksum = md5($someString);
echo $checksum;
result: 76d80224611fc919a5d54f0ff9fba446
Java:
String someString = "qwe";
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
String checksum = new BigInteger(1, messageDigest.digest(someString
.getBytes())).toString(16);
System.out.println(checksum);
result: 76d80224611fc919a5d54f0ff9fba446
As you can see, it works
With bkey:
PHP:
$hexString = '90aa';#sample value
$bkey = pack('H*',$hexString);
$someString='qwe';#sample value
$checksum = md5($someString.$bkey);
echo $checksum;
result: 18f5f1a9bf898131945dd9e315759fe4
Java:
public static void main(String[] args) throws NoSuchAlgorithmException {
String hexString = "90aa";
String bkey = hexToString(hexString);
String someString = "qwe";
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
String input = someString + bkey;
String checksum = new BigInteger(1, messageDigest.digest(input
.getBytes())).toString(16);
System.out.println(checksum);
}
public static String hexToString(String hex) {
StringBuilder output = new StringBuilder();
for (int i = 0; i < hex.length(); i += 2) {
String str = hex.substring(i, i + 2);
output.append((char) Integer.parseInt(str, 16));
}
return output.toString();
}
result: 44bb634dee436833dd65caa5043ffeb9
As you can see results are different.
How to convert hex String to String to get the same result?
The problem is not actually in your Java code, but in the PHP code.
The line $checksum = md5($someString+$bkey); does not do what you think it does, it should be:
$checksum = md5($someString . $bkey); # use concatenate, not sum
Although, that gives abetter PHP MD5, but does not help make the Java code match the PHP
EDIT
The problem on the Java side is in the character encoding. The Java char values for the inoacked versions of 90aa are not valid unicode characters. Thus the toByteArray() ,ethods ar enot doing great things. If you treat all of the Java code at a byte level (and ignore any high-bytes in any chars in the Java), then you get the same result as the PHP:
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String hexString = "90aa";
byte[] bkey = hexToString(hexString);
String someString = "qwe";
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] input = join(stringToBytes(someString), bkey);
String checksum = new BigInteger(1, messageDigest.digest(input)).toString(16);
System.out.println(checksum);
System.out.println(Charset.defaultCharset().displayName());
}
private static byte[] join(byte[] a, byte[] b) {
// join two byte arrays
final byte[] ret = new byte[a.length + b.length];
System.arraycopy(a, 0, ret, 0, a.length);
System.arraycopy(b, 0, ret, a.length, b.length);
return ret;
}
public static byte[] hexToString(String hex) {
// hexToString that works at a byte level, not a character level
byte[] output = new byte[(hex.length() + 1) / 2];
for (int i = hex.length() - 1; i >= 0; i -= 2) {
int from = i - 1;
if (from < 0) {
from = 0;
}
String str = hex.substring(from, i + 1);
output[i/2] = (byte)Integer.parseInt(str, 16);
}
return output;
}
public static byte[] stringToBytes(final String input) {
// unlike Stirng.toByteArray(), we ignore any high-byte values of the characters.
byte[] ret = new byte[input.length()];
for (int i = input.length() - 1; i >=0; i--) {
ret[i] = (byte)input.charAt(i);
}
return ret;
}
The above Java code produces the MD5sum 18f5f1a9bf898131945dd9e315759fe4 which is what PHP gives too

Looking for javascript md5 method in java implementation

I have Javascript md5 on site auth.
I need to implement only this function:
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
I need help with following methods:
Convert an array of little-endian words to a hex string:
function binl2hex(binarray)
{
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for(var i = 0; i < binarray.length * 4; i++)
{
str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
}
return str;
}
Convert a string to an array of little-endian words
If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
function str2binl(str)
{
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz)
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
return bin;
}
If you're just looking to implement MD5, that's something which is built in to java.
https://stackoverflow.com/a/415971/576519
I have developed a simple Java MD5 function that is compatible with a standard JavaScript function you can download the class from: http://developersfound.com/HexMD5.zip
Here is the code:
/* This MD5 hash class is compatible with the JavaScript MD5 has code found at http://pajhome.org.uk/crypt/md5/md5.html */
package com.DevFound;
import java.security.MessageDigest;
public class HexMD5 {
public static String getMD5Str(String inputVal)throws Exception
{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(inputVal.getBytes());
byte byteData[] = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
for (int i=0;i<byteData.length;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}
I haven't tested this code with your particular JavaScript md5 function but I have listed the function that it is compatible with in the comment at the top of the code.

Make SHA1 encryption on Android?

Can you suggest me about how to encrypt string using SHA1 algorithm ?
I've searched about it. But no luck.
Thanks in advance.
binnyb's convertToHex method is not working properly. A more correct one that works for me is:
private static String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9)) {
buf.append((char) ('0' + halfbyte));
}
else {
buf.append((char) ('a' + (halfbyte - 10)));
}
halfbyte = data[i] & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}
public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] sha1hash = new byte[40];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
sha1hash = md.digest();
return convertToHex(sha1hash);
}
use the SHA1 method to get your sha1 string.
Update: providing a complete answer
here are 2 methods i have found while searching for a sha1 algorithm implementation:
private static String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
int length = data.length;
for(int i = 0; i < length; ++i) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) ('0' + halfbyte));
else
buf.append((char) ('a' + (halfbyte - 10)));
halfbyte = data[i] & 0x0F;
}
while(++two_halfs < 1);
}
return buf.toString();
}
public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] sha1hash = new byte[40];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
sha1hash = md.digest();
return convertToHex(sha1hash);
}
use the SHA1 method to get your sha1 string. I have not confirmed that this is indeed a sha1, but it works for my apps.
I've answered this before (How to SHA1 hash a string in Android?) but it fits here, as well:
Android comes with Apache's Commons Codec so you can simply use the following line to create a SHA-1 hexed String:
String myHexHash = DigestUtils.shaHex(myFancyInput);
That is the old deprecated method you get with Android 4 by default. The new versions of DigestUtils bring all flavors of shaHex() methods like sha256Hex() and also overload the methods with different argument types.
Of course, there is more functionality in DigestUtils and the rest of Commons Codec. Just have a look.
http://commons.apache.org/proper/commons-codec//javadocs/api-release/org/apache/commons/codec/digest/DigestUtils.html
EDIT:
If you get a ClassNotFoundError you will have to explicitly add commons-codec as dependency (even though it should come with Android as transitive dependency), in Maven e.g.:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.7</version>
</dependency>
And also, you will have to change the call to:
String myHexHash = new String(Hex.encodeHex(DigestUtils.sha512(myFancyInput)));
(My humble guess is that this is probably due to a ClassLoader issue (class name collision) in the Android VM - which would actually prove that the commons-codec classes are already present...)
See also:
https://stackoverflow.com/a/9284092/621690
binnyb set me on the right track, but I found some more, easier to understand code here:
http://www.coderanch.com/t/526487/java/java/Java-Byte-Hex-String
private static String convertToHex(byte[] data) {
StringBuilder sb = new StringBuilder(data.length * 2);
Formatter fmt = new Formatter(sb);
for (byte b : data) {
fmt.format("%02x", b);
}
return sb.toString();
}

Categories