I have a java code that want converted to php .
public String getSHA1Hash(String input) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String SHA1Hash = null;
MessageDigest md = MessageDigest.getInstance("SHA1");
md.reset();
byte[] buffer = input.getBytes("UTF-8");
md.update(buffer);
byte[] digest = md.digest();
String hexStr = "";
for (int i = 0; i < digest.length; i++) {
hexStr += Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1);
SHA1Hash = hexStr;
}
return SHA1Hash;
help
PHP has a function sha1() that creates a sha1 hash from the input string. No need to convert the java function and rebuild the logic.
PHP has a native function to hash sha1 strings:
sha1 — Calculate the sha1 hash of a string
Example from Manual:
$str = 'apple';
if (sha1($str) === 'd0be2dc421be4fcd0172e5afceea3970e2f3d940') {
echo "Would you like a green or red apple?";
}
This will give the same output as your Java code would give for "apple".
Related
Android java SHA256 and C# sha256 give different values. I want java to be same as c#.
c# code:
private static string _getHashSha256(string inputString)
{
string hashString = string.Empty;
using (SHA256Managed hashstring = new SHA256Managed())
{
byte[] bytes = UTF32Encoding.UTF32.GetBytes(inputString);
byte[] hash = hashstring.ComputeHash(bytes);
foreach (byte x in hash)
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
input "111", result "f4b5625de0c6abd88521b87d39f5a4fe33935f27c4ac38a63575ad43d36c7fbb"
android java code:
String password="111";
MessageDigest digest=null;
String hash;
try {
digest = MessageDigest.getInstance("SHA-256");
digest.update(password.getBytes("UTF-32"));
hash = bytesToHexString(digest.digest());
Log.i("sha256", hash);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e1) {
z = "hash code error: " + e1.getMessage();
}
input is "111". result "12215d42454c57aa1039367b66509e53dcd2d6f9a6e80f9d00b2439ea7ebd43f"
please help me guys!
Thanks guys.
I found the problem was when java converts string to bytes by utf-32, there is additional 4 bytes preceded. it changed resulting sha256.
So I removed that initial 4 bytes as follows:
String password="111";
MessageDigest digest=null;
String hash;
byte[] bbb = user_pass.getBytes("UTF-32");
byte[] ccc = new byte[bbb.length - 4];
System.arraycopy(bbb, 4, ccc, 0, bbb.length - 4);
digest = MessageDigest.getInstance("SHA-256");
digest.update(ccc);
hash_password = bytesToHexString(digest.digest());
I use this code in PHP to encrypt the password:
return sha1("kD0a1".md5("xA4".$password)."f4A");
Does anyone know an effective replacement for use in Android? I tried different functions for MD5 and SHA1 but in Java it always generates a different HASH than in PHP.
For example, as follows:
public static String passwordHash(String password) {
return sha1("kD0a1"+md5("xA4"+password)+"f4A");
}
public static String md5(String s) {
try {
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
public static String sha1(String clearString) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
messageDigest.update(clearString.getBytes("UTF-8"));
byte[] bytes = messageDigest.digest();
StringBuilder buffer = new StringBuilder();
for (byte b : bytes) {
buffer.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return buffer.toString();
}
catch (Exception ignored) {
ignored.printStackTrace();
return null;
}
}
However, PHP and Java will return a different HASH string to me.
PASS: test
PHP: 17bf2c08f4b9447cf8316736e13833316d3edc23
JAVA: 8434696e252b89af0db033eb255c88a91a42ce14
However, if I enter "passTest" for example, it will generate a hash correctly
PASS: passTest
PHP: db4aedf1d4072b7b645996394aa74743f14eeb7a
JAVA: db4aedf1d4072b7b645996394aa74743f14eeb7a
And "passwordTest" is wrong again.
PASS: passwordTest
PHP: 1ad47c24d556187f1de5db66ff623bbe08a27f33
JAVA: 0f058b3aea48e69c028a7ee2693a98d6074b10a8
I can't explain that sometimes it works and sometimes it doesn't, and at the same time it just changes the String for the password.
Do you think there could be a problem with coding or something? I thought TextView did it, but even if I enter a String outside of TextView, it behaves the same way.
Thank you in advance for any advice.
I would add that I am testing on SDK 31
M.
following code may help you to achieve what you want, it's a method named hashing and salt password, furthermore, the salt method prevents the collision of passwords that have been registered on your database
public static String hashPassword(String password) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.reset();
md.update(password.getBytes());
byte[] mdArray = md.digest();
StringBuilder sb = new StringBuilder(mdArray.length * 2);
for(byte b : mdArray) {
int v = b & 0xff;
if(v < 16)
sb.append('0');
sb.append(Integer.toHexString(v));
}
return sb.toString();
}
here is the salt method
public static String getSalt() throws NoSuchAlgorithmException {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[32];
sr.nextBytes(salt);
return Base64.getEncoder().encodeToString(salt);
}
for further reading about different hashing&salting password, consult the below link, it might help you to solid your understands
https://howtodoinjava.com/java/java-security/how-to-generate-secure-password-hash-md5-sha-pbkdf2-bcrypt-examples/
NB: you should use a strong implementation to hash your password to prevent cracking
I have my php application where when I created the user I ran this.
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password
$userPwd = hash('sha512', $userPwd . $random_salt);
Next when I try to login upon the having captured the password I hash via this javascript
p.value = hex_sha512(userPwdControl.value);
Then in the ran this
$hashPassword = hash('sha512', $userPassword . $row1['userSalt']);
All above codes works via php.
Now via my android I want to do this function p.value = hex_sha512(userPwdControl.value); to get the hash and I am trying out first via java codes as below. But I got empty results below.
StringBuffer stringBuffer = new StringBuffer();
try {
String message = "myPass";
MessageDigest digest = MessageDigest.getInstance("512");
byte[] hashedBytes = digest.digest(message.getBytes("UTF-8"));
for (int i = 0; i < hashedBytes.length; i++) {
stringBuffer.append(Integer.toString((hashedBytes[i] & 0xff) + 0x100, 16)
.substring(1));
}
stringBuffer.toString();
} catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
}
System.out.println("TEST :"+stringBuffer);
Can you try the code below. Did some minor changes in your code.
String resultString = "";
try {
byte[] buffer = password.getBytes();
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(buffer);
byte[] digest = md.digest();
for(int i = 0 ; i < digest.length ; i++) {
int b = digest[i] & 0xff;
if(Integer.toHexString(b).length() == 1)
resultString = resultString + "0";
resultString = resultString + Integer.toHexString(b);
}
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
Your problem seems to be solved already, but I would strongly recommend to switch to a more safe hashing algorithm. A single SHA-512 cannot protect your users passwords because it is way too fast (1 Giga SHA-512 per second) and therefore can be brute-forced too easily.
What you need, is hash function with a cost factor, like BCrypt, PBKDF2 or SCrypt. PHPs function password_hash() currently implements BCrypt, a compatible implementation you can get with jBCrypt.
Trying to create a secure login I have decided to create an MD5 hash using the following code, adapted a small bit from How can I generate an MD5 hash?
However, this doesn't generate the same hash when the user is created as is created on the login page. why is this as I thought the hash was unique to each string.
MessageDigest messageDigest = null;
try{
messageDigest = MessageDigest.getInstance("MD5");
}catch(NoSuchAlgorithmException e){
System.out.println("Error: " + e);
}
messageDigest.reset();
messageDigest.update(inPassword.getBytes());
byte[] digest = messageDigest.digest();
BigInteger bigInt = new BigInteger(1, digest);
String encodedPass = bigInt.toString(16);
while (encodedPass.length() < 32) {
encodedPass = "0" + encodedPass;
}
inPassword = encodedPass;
This is at least part of the problem:
messageDigest.update(inPassword.getBytes());
That's using the platform default encoding to convert the password to bytes. That could vary on each system you run it on. I would strongly suggest you specify an encoding - ideally one which will cope with all Unicode characters (e.g. UTF-8).
You might also want to think about salting, and using something better than MD5, and I'm not sure about your conversion from byte[] to hex - it might be okay, but I'd find a library to just do the whole thing without using BigInteger.
Following is the complete code that you might need.
import java.io.FileInputStream;
import java.security.MessageDigest;
public class MD5CheckSumExample
{
public static void main(String[] args)throws Exception
{
MessageDigest md = MessageDigest.getInstance("MD5");
FileInputStream fis = new FileInputStream("c:\\loging.log");
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
};
byte[] mdbytes = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < mdbytes.length; i++) {
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("Digest(in hex format):: " + sb.toString());
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
for (int i=0;i<mdbytes.length;i++) {
String hex=Integer.toHexString(0xff & mdbytes[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
System.out.println("Digest(in hex format):: " + hexString.toString());
}
}
Try this, it works for me:
messageDigest.update(myString.getBytes(), 0, myString.length());
The rest of your code seems correct. Hope it helps! :)
I have a SQL table with usernames and passwords. The passwords are encoded using MessageDigest's digest() method. If I encode a password - let's say "abcdef12" - with MessageDigest's digest() method and then convert it to hexadecimal values, the String is different than if I do the same using PHP's SHA1-method. I'd expect these values to be exactly the same though.
Code that is used to encode the passwords:
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] passbyte;
passbyte = "abcdef12".getBytes("UTF-8");
passbyte = md.digest(passbyte);
The conversion of the String to hexadecimal is done using this method:
public static String convertStringToHex(String str) {
char[] chars = str.toCharArray();
StringBuffer hex = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
hex.append(Integer.toHexString((int) chars[i]));
}
return hex.toString();
}
Password: abcdef12
Here's the password as returned by a lot of SHA1-hash online generators and PHP SHA1()-function: d253e3bd69ce1e7ce6074345fd5faa1a3c2e89ef
Here's the password as encoded by MessageDigest: d253e3bd69ce1e7ce674345fd5faa1a3c2e2030ef
Am I forgetting something?
Igor.
Edit: I've found someone with a similar problem: C# SHA-1 vs. PHP SHA-1...Different Results? . The solution was to change encodings.. but I can't change encodings on the server-side since the passwords in that SQL-table are not created by my application.
I use client-side SHA1-encoding using a JavaScript SHA1-class (more precisely: a Google Web Toolkit-class). It works and encodes the string as expected, but apparently using ASCII characters?..
I have the same digest as PHP with my Java SHA-1 hashing function:
public static String computeSha1OfString(final String message)
throws UnsupportedOperationException, NullPointerException {
try {
return computeSha1OfByteArray(message.getBytes(("UTF-8")));
} catch (UnsupportedEncodingException ex) {
throw new UnsupportedOperationException(ex);
}
}
private static String computeSha1OfByteArray(final byte[] message)
throws UnsupportedOperationException {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(message);
byte[] res = md.digest();
return toHexString(res);
} catch (NoSuchAlgorithmException ex) {
throw new UnsupportedOperationException(ex);
}
}
I've added to my unit tests:
String sha1Hash = StringHelper.computeSha1OfString("abcdef12");
assertEquals("d253e3bd69ce1e7ce6074345fd5faa1a3c2e89ef", sha1Hash);
Full source code for the class is on github.
Try this - it is working for me:
MessageDigest md = MessageDigest.getInstance(algorithm);
md.update(original.getBytes());
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (byte b : digest) {
sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
Regards,
Konki
It has nothing to do with the encodings. The output would be entirely different.
For starters, your function convertStringToHex() doesn't output leading zeros, that is, 07 becomes just 7.
The rest (changing 89 to 2030) is also likely to have something to do with that function. Try looking at the value of passbyte after passbyte = md.digest(passbyte);.
Or try this:
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(clearPassword.getBytes("UTF-8"));
return new BigInteger(1 ,md.digest()).toString(16));
Cheers Roy