En Objective C, j'ai utilisé le code suivant pour hacher une chaîne:
-(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]
];
}
Maintenant, j'ai besoin de la même chose pour Android mais je ne sais pas comment le faire. J'ai cherché un exemple à ceci: Faire du cryptage SHA1 sur Android? mais cela ne me donne pas le même résultat que sur l'iPhone. Est-ce que quelqu'un peut me diriger dans la bonne direction?
Vous n'avez pas besoin d'andorid pour cela. Vous pouvez simplement le faire en Java simple.
Avez-vous essayé un exemple simple Java et voyez si cela retourne le sha1 correct?).
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);
}
}
Partagez également ce que vous attendez de sha1. Peut-être que ObjectC fait le mal.
Une méthode SHA-1 plus simple: (mis à jour à partir des suggestions du commentateur, utilisant également un algorithme d'octets-> chaîne massivement plus efficace)
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 );
}
Si vous pouvez vous en tirer avec avec Guava, c'est de loin le moyen le plus simple de le faire , et vous n'avez pas à réinventer la roue:
final HashCode hashCode = Hashing.sha1().hashString(yourValue, Charset.defaultCharset());
Vous pouvez alors prendre la valeur hachée et l'obtenir sous la forme d'un byte[]
, en tant que int
, ou en tant que long
.
Pas d'emballage dans une prise d'essai, pas de manigances. Et si vous décidez d'utiliser quelque chose d'autre que SHA-1, Guava prend également en charge sha256, sha 512 et quelques-uns dont je n'avais jamais entendu parler, comme adler32 et murmur3.
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();
Totalement basé sur la réponse de @ Whymarrh, voici mon implémentation, testée et fonctionnant correctement, sans dépendance:
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;
}
}
Android est fourni avec Apache's Commons Codec - ou vous l'ajoutez comme dépendance. Alors fais:
String myHexHash = DigestUtils.shaHex(myFancyInput);
C'est l'ancienne méthode dépréciée que vous obtenez avec Android 4 par défaut. Les nouvelles versions de DigestUtils apportent toutes les saveurs des méthodes shaHex () comme sha256Hex () et surchargent également les méthodes avec différents types d'arguments.
La méthode que vous recherchez n'est pas spécifique à Android, mais à Java en général. Vous recherchez le MessageDigest (import Java.security.MessageDigest
).
Une implémentation d'une méthode sha512(String s)
peut être vue ici , et le changement pour un hachage SHA-1 changerait la ligne 71 en:
MessageDigest md = MessageDigest.getInstance("SHA-1");