4

Can you suggest me about how to encrypt string using SHA1 algorithm ? I've searched about it. But no luck.

Thanks in advance.

Mikael Engver
  • 4,634
  • 4
  • 46
  • 53
Ferdinand
  • 1,193
  • 4
  • 23
  • 43
  • 6
    SHA1 is not an encryption algorithm, it's a hash algorithm. Once you hash your message, it's impossible to "dehash" it. Just so you know. More info here: http://en.wikipedia.org/wiki/Hash_algorithm. – AVH Apr 22 '11 at 15:37
  • IMHO, it is not enough to simply hash the string once. Consider salting the string with a random seed and "recursively" hashing the salted string at least 1000 times. You will then need to store the random seed. – JAL Apr 22 '11 at 19:40
  • A simpler SHA-1 method: (updated from the commenter's suggestions, also using a massively more efficient byte->string algorithm) See this link http://stackoverflow.com/questions/5980658/how-to-sha1-hash-a-string-in-android – M.Ganji Jun 03 '15 at 06:45

4 Answers4

9

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

Mikael Engver
  • 4,634
  • 4
  • 46
  • 53
2

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

Community
  • 1
  • 1
Risadinha
  • 16,058
  • 2
  • 88
  • 91
2

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.

james
  • 26,141
  • 19
  • 95
  • 113
  • Your indentation came up looking a little inconsistent, so I made it more consistent. If you don't like it, just roll back. :) – alternative Apr 22 '11 at 15:42
  • 1
    Also keep in mind that byte[] is a more compact format then a hex string and therefore its probably more efficient to store it as a byte[] until you need to present the data to the user, in which case the user expects hexadecimal. – alternative Apr 22 '11 at 15:43
  • about the indentation.. i just copy and pasted from Eclipse. i can't seem to get it into a good format after copy/paste. Am i doing something wrong? ha – james Apr 22 '11 at 15:49
  • Guys' I've compared code with online encoder. But no luck: http://ratfactor.com/sha1 There is an issue encoding ? – Ferdinand Apr 22 '11 at 17:50
  • 2
    The problem is this convertToHex method is skipping every other converted character in the result. For example, the has of "Have a nice day!" should be 56cb5d30886e7715f9861220e940758abcbe5473 but is 5c538671f812e478bb57. – Thane Anthem Apr 22 '11 at 22:03
  • 1
    A working method to convert to hex from byte[] array is posted at http://forums.xkcd.com/viewtopic.php?f=11&t=16666&p=553936 – Thane Anthem Apr 22 '11 at 22:11
  • Thank you! One line of above method should be while(two_halfs++ < 1); This works for me. – Ferdinand Apr 22 '11 at 23:04
0

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();
}
Ruben
  • 796
  • 3
  • 9
  • 21