it-swarm.com.de

Wie SHA1 Hash eine Zeichenfolge in Android?

In Objective C habe ich den folgenden Code zum Hashing einer Zeichenfolge verwendet:

-(NSString *) sha1:(NSString*)stringToHash {    
    const char *cStr = [stringToHash UTF8String];
    unsigned char result[20];
    CC_SHA1( cStr, strlen(cStr), result );
    return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
        result[0], result[1], result[2], result[3], 
        result[4], result[5], result[6], result[7],
        result[8], result[9], result[10], result[11],
        result[12], result[13], result[14], result[15],
        result[16], result[17], result[18], result[19]
        ];  
}

Jetzt brauche ich dasselbe für Android, kann aber nicht herausfinden, wie es geht. Ich habe nach folgendem Beispiel gesucht: SHA1-Verschlüsselung unter Android erstellen? Aber das gibt mir nicht das gleiche Ergebnis wie auf dem iPhone. Kann mich jemand in die richtige Richtung weisen?

65
Martin

Dafür brauchst du kein Andorid. Sie können es einfach in einfachem Java tun.

Haben Sie versucht, ein einfaches Java Beispiel und sehen, ob dies die richtige sha1 zurückgibt.

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);
    }
}

Teilen Sie auch mit, was Sie von sha1 erwarten. Vielleicht macht ObjectC es falsch.

152
Amir Raminfar

Eine einfachere SHA-1-Methode: ( aktualisiert von den Vorschlägen des Kommentators, auch unter Verwendung eines massiv effizienteren Byte-> String-Algorithmus )

String sha1Hash( String toHash )
{
    String hash = null;
    try
    {
        MessageDigest digest = MessageDigest.getInstance( "SHA-1" );
        byte[] bytes = toHash.getBytes("UTF-8");
        digest.update(bytes, 0, bytes.length);
        bytes = digest.digest();

        // This is ~55x faster than looping and String.formating()
        hash = bytesToHex( bytes );
    }
    catch( NoSuchAlgorithmException e )
    {
        e.printStackTrace();
    }
    catch( UnsupportedEncodingException e )
    {
        e.printStackTrace();
    }
    return hash;
}

// http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-Java
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 );
}
35
Adam

Wenn Sie mit Guava durchkommen können , ist dies bei weitem der einfachste Weg , und Sie müssen das Rad nicht neu erfinden:

final HashCode hashCode = Hashing.sha1().hashString(yourValue, Charset.defaultCharset());

Sie können dann den gehashten Wert als byte[], als int oder als long.

Kein Einwickeln in einen Versuchsfang, keine Spielereien. Und wenn Sie sich entscheiden, etwas anderes als SHA-1 zu verwenden, unterstützt Guava auch sha256, sha 512 und einige, von denen ich noch nie gehört hatte, wie adler32 und murmur3.

28
yarian
final MessageDigest digest = MessageDigest.getInstance("SHA-1");
result = digest.digest(stringToHash.getBytes("UTF-8"));

// Another way to construct HEX, my previous post was only the method like your solution
StringBuilder sb = new StringBuilder();

for (byte b : result) // This is your byte[] result..
{
    sb.append(String.format("%02X", b));
}

String messageDigest = sb.toString();
15
Suphi ÇEVİKER

Ganz basierend auf der Antwort von @ Whymarrh ist dies meine Implementierung, getestet und funktioniert einwandfrei, keine Abhängigkeiten:

public static String getSha1Hex(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;
    }
}
15
cprcrack

Android wird mit Apaches Commons Codec geliefert - oder Sie fügen ihn als Abhängigkeit hinzu. Dann mach:

String myHexHash = DigestUtils.shaHex(myFancyInput);

Dies ist die alte veraltete Methode, die Sie standardmäßig mit Android 4 erhalten. Die neuen Versionen von DigestUtils bieten alle Varianten von shaHex () -Methoden wie sha256Hex () und überladen die Methoden mit verschiedenen Argumenttypen.

http://commons.Apache.org/proper/commons-codec//javadocs/api-release/org/Apache/commons/codec/digest/DigestUtils.html

8
Risadinha

Die Methode, nach der Sie suchen, ist nicht spezifisch für Android, sondern für Java im Allgemeinen. Sie suchen nach MessageDigest (import Java.security.MessageDigest).

Eine Implementierung einer sha512(String s) -Methode ist zu sehen hier , und die Änderung für einen SHA-1-Hash würde Zeile 71 folgendermaßen ändern:

MessageDigest md = MessageDigest.getInstance("SHA-1");
2
Whymarrh