MessageDigest hachages différemment sur différentes machines
Je vais avoir un problème avec MessageDigest de retour différentes valeurs de hachage sur des ordinateurs différents.
Un ordinateur exécute une version 32 bits de Java sur Windows Vista et l'autre est en cours d'exécution 64 bits de Java sur Mac OS. Je ne sais pas si c'est parce que MessageDigest est dépend de la machine, ou j'ai besoin de spécifier explicitement un codage de caractères quelque part, ou peut-être quelque chose d'autre. Voici l'
code:
public static boolean authenticate(String salt, String encryptedPassword,
char[] plainTextPassword ) throws NoSuchAlgorithmException {
//do I need to explcitly specify character encoding here? -->
String saltPlusPlainTextPassword = salt + new String(plainTextPassword);
MessageDigest sha = MessageDigest.getInstance("SHA-512");
//is this machine dependent? -->
sha.update(saltPlusPlainTextPassword.getBytes());
byte[] hashedByteArray = sha.digest();
//or... perhaps theres a translation problem here? -->
String hashed = new String(hashedByteArray);
return hashed.equals(encryptedPassword);
}
Doit exécuter ce code différemment sur ces deux machines différentes?
Si elle est dépend de la machine de la façon dont je l'ai écrit, est-il une autre façon de hachage de ces mots de passe qui n'est plus portable? Merci!
Edit:::::
C'est le code que j'utilise pour générer les sels:
public static String getSalt() {
int size = 16;
byte[] bytes = new byte[size];
new Random().nextBytes(bytes);
return org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(bytes);
}
Solution:::
Grâce à la solution retenue, j'ai pu corriger mon code:
public static boolean authenticate_(String salt, String encryptedPassword,
char[] plainTextPassword ) throws NoSuchAlgorithmException, UnsupportedEncodingException {
//This was ok
String saltPlusPlainTextPassword = salt + new String(plainTextPassword);
MessageDigest sha = MessageDigest.getInstance("SHA-512");
//must specify "UTF-8" encoding
sha.update(saltPlusPlainTextPassword.getBytes("UTF-8"));
byte[] hashedByteArray = sha.digest();
//Use Base64 encoding here -->
String hashed = org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(hashedByteArray);
return hashed.equals(encryptedPassword);
}
Oui, il y a un autre sel pour chaque mot de passe.
Donc, une fois que vous générez le sel pour chaque mot de passe, où en êtes-vous de les stocker? Est-ce un endroit où les applications peuvent y avoir accès?
Oui, le sel est stocké dans le même dossier que le mot de passe crypté.
OriginalL'auteur Chris Dutrow | 2010-06-19
Vous devez vous connecter pour publier un commentaire.
Codages sont à l'origine des problèmes. D'abord ici:
Qui va utiliser le encodage par défaut de la machine. Mauvaise idée. Spécifiez "UTF-8" comme une solution simple. (C'est la garantie d'être présent.)
Suivante, ce qui provoque des problèmes:
hashedByteArray
est des données binaires arbitraires. Pour convertir en toute sécurité au texte, soit d'utiliser un encodage base 64 ou tout simplement hex. Encore une fois, vous êtes actuellement en utilisant le codage par défaut, qui varient d'une machine à l'autre. Il y a des charges de la 3e partie des bibliothèques pour l'encodage base64 en Java.OriginalL'auteur
Probablement Jon Skeet la solution ci-dessus est la cause, et ses recommandations devraient certainement être pris en compte, mais une autre cause possible est un malentendu de sel.
Le sel est un semi-secrète valeur aléatoire est appliquée à une Chaîne de caractères avant de hachage. Cela rend plus difficile pour effectuer une attaque par force brute en essayant de deviner ce originaire de Chaîne est parce que le sel est probablement inconnu de l'attaquant.
Sel valeurs diffèrent généralement d'une installation à. Il est possible que la cause réelle est juste que vous avez le sel valeurs définies différemment sur les différentes machines.
Étant donné que vous êtes déjà à l'aide de communes codec, c'est la façon dont vous devriez en base 64 encoder le code de hachage.
OriginalL'auteur