How to Hash a String in Android

How to hash a string in Android?

This snippet calculate md5 for any given string

public String md5(String s) {
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();

// Create Hex String
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 "";
}

Source: http://www.androidsnippets.com/snippets/52/index.html

Hope this is useful for you

SHA-512 hashing with Android

The other questions you saw use salt so just don't use salt like so:

MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] digest = md.digest("Hello, world!".getBytes());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println(sb);

Based on this answer.

How to SHA1 hash a string in Android?

You don't need andorid for this. You can just do it in simple java.

Have you tried a simple java example and see if this returns the right sha1.

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class AeSimpleSHA1 {
private static String convertToHex(byte[] data) {
StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4) & 0x0F;
int two_halfs = 0;
do {
buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}

public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] textBytes = text.getBytes("iso-8859-1");
md.update(textBytes, 0, textBytes.length);
byte[] sha1hash = md.digest();
return convertToHex(sha1hash);
}
}

Also share what your expected sha1 should be. Maybe ObjectC is doing it wrong.

How can I hash the password in my app

Ah ok. As per discussion in Comment. So in your class that takes the password as input you have to implement this method.

So what you have to do is implement the answer method in your class itself. So add below method in your class -

public String md5(String s) {
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();

// Create Hex String
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 "";
}

Now in your Async task you are doing this -

 String password = editTextPassword.getText().toString();

Instead pass this value to your md5 method and get the hashed code as password.

String password = md5(editTextPassword.getText().toString());

Which hashing algorithms are available in Android?

As someone already mentioned, there's not a clear way to find out which algorithms are available. So what I decided to do, is to create a helper for that.

import android.util.Base64;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.KeySpec;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

/**
* Created by sergi.castellsague on 04/05/2014.
*/
public class SecurityManager
{
private static final int ITERATIONS = 1000;

public enum HashMethod
{
PBKDF2(){
@Override
public String getHashString()
{
return "PBKDF2WithHmacSHA1";
}
}, SHA512(){
@Override
public String getHashString() {
return "SHA-512";
}
}, SHA384() {
@Override
public String getHashString() {
return "SHA-384";
}
}, SHA256() {
@Override
public String getHashString () {
return "SHA-256";
}
}
, SHA1()
{
@Override
public String getHashString() {
return "SHA-1";
}
};

public abstract String getHashString();

}

public static HashMethod getAppropriateHash()
{
HashMethod method = null;

if ( isPBKDFAvailable() )
{
method = HashMethod.PBKDF2;
}
else if( isDigestAvailable( HashMethod.SHA512.getHashString() ) )
{
method = HashMethod.SHA512;
}
else if( isDigestAvailable( HashMethod.SHA384.getHashString() ) )
{
method = HashMethod.SHA384;
}
else if( isDigestAvailable( HashMethod.SHA256.getHashString() ) )
{
method = HashMethod.SHA256;
}
else if( isDigestAvailable( HashMethod.SHA1.getHashString() ) )
{
method = HashMethod.SHA1;
}

return method;
}

private static boolean isPBKDFAvailable()
{
try
{
SecretKeyFactory.getInstance( HashMethod.PBKDF2.getHashString() );
}
catch ( Exception notAvailable)
{
return false;
}
return true;
}

private static boolean isDigestAvailable( String method )
{
try
{
MessageDigest.getInstance( method );
}
catch ( Exception notAvailable )
{
return false;
}

return true;
}

public static String getHashedPassword( HashMethod method, String password )
{
String hashed;

if ( HashMethod.PBKDF2.getHashString().equals( method.getHashString() ) )
{
hashed = generatePBKDF( password );
}
else
{
hashed = password;
for ( int i = 0; i < ITERATIONS; i++ )
{
hashed = generateDigestPassword( password, method.getHashString() );
}
}

return hashed;
}

private static String generatePBKDF( String password )
{
// Generate a 512-bit key
final int outputKeyLength = 512;

char[] chars = new char[password.length()];
password.getChars( 0, password.length(), chars, 0 );
byte[] salt = "salt_on_client_is_funny".getBytes(); // In security terms, this is worthess. However, it's required.

byte[] hashedPassBytes = new byte[0];
try
{
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance( HashMethod.PBKDF2.getHashString() );
KeySpec keySpec = new PBEKeySpec( chars, salt, ITERATIONS, outputKeyLength );

hashedPassBytes = secretKeyFactory.generateSecret( keySpec ).getEncoded();
}
catch ( Exception shouldNotHappen )
{}

return Base64.encodeToString( hashedPassBytes, Base64.DEFAULT );
}

private static String generateDigestPassword( String password, String algorithm )
{
byte[] digest = new byte[0];
byte[] buffer = password.getBytes();

try {
MessageDigest messageDigest = MessageDigest.getInstance( algorithm );
messageDigest.reset();
messageDigest.update( buffer );
digest = messageDigest.digest();
}
catch ( NoSuchAlgorithmException ex )
{}

return Base64.encodeToString(digest, Base64.DEFAULT);
}
}

The usage is pretty simple:

String password = "BestPasswordEver123!!";
SecurityManager.HashMethod hashMethod = SecurityManager.getAppropriateHash();
SecurityManager.getHashedPassword( hashMethod, password )

Oh, and note that depending on:

  1. Algorithm used
  2. Amount of iterations
  3. Device

The calculation, might be something from 0.5s to 10s (or more...), so you better do it in an other Thread =)

How to write a hash function in Android similar to the Python function?

You can try the following code snippet,

String text = "PARAMETER123";

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] textBytes = text.getBytes("UTF-8");
md.update(textBytes, 0, textBytes.length);
byte[] sha1hash = md.digest();

String encrypted_text = = convertToHex(sha1hash);

and the convertToHex() method

private static String convertToHex(byte[] data) {
StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4) & 0x0F;
int two_halfs = 0;
do {
buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}

This will convert a UTF-8 based text into a SHA1 hex.

Reference: https://stackoverflow.com/a/5980789/2506025

How can I calculate the SHA-256 hash of a string in Android?

The PHP function bin2hex means that it takes a string of bytes and encodes it as a hexadecimal number.

In the Java code, you are trying to take a bunch of random bytes and decode them as a string using your platform's default character encoding. That isn't going to work, and if it did, it wouldn't produce the same results.

Here's a quick-and-dirty binary-to-hex conversion for Java:

static String bin2hex(byte[] data) {
StringBuilder hex = new StringBuilder(data.length * 2);
for (byte b : data)
hex.append(String.format("%02x", b & 0xFF));
return hex.toString();
}

This is quick to write, not necessarily quick to execute. If you are doing a lot of these, you should rewrite the function with a faster implementation.



Related Topics



Leave a reply



Submit