MessageDigest在不同的机器上具有不同的哈希值 [英] MessageDigest hashes differently on different machines

查看:271
本文介绍了MessageDigest在不同的机器上具有不同的哈希值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



一台计算机在Windows Vista上运行32位Java,另一台运行在运行Windows Vista的另一台计算机上Mac OS上的64位Java。我不确定是因为MessageDigest是依赖于机器的,还是我需要明确指定某个地方的字符编码,或者是其他的东西。以下是
代码:

  public static boolean authenticate(String salt,String encryptedPassword,
char [] plainTextPassword)抛出NoSuchAlgorithmException {

//我需要在这里明确指定字符编码吗? - >
String saltPlusPlainTextPassword = salt + new String(plainTextPassword);

MessageDigest sha = MessageDigest.getInstance(SHA-512);

//是否依赖于此机器? - >
sha.update(saltPlusPlainTextPassword.getBytes());
byte [] hashedByteArray = sha.digest();

//或...也许这里有翻译问题? - >
String hashed = new String(hashedByteArray);

返回hashed.equals(encryptedPassword);
}

这段代码应该在这两台不同的机器上执行不同的操作吗?
如果它的机器依赖于我写的方式,是否有另一种方式散列这些更便携的密码?谢谢!


::::



这是我用来生成盐:

  public static String getSalt(){
int size = 16;
byte [] bytes = new byte [size];
new Random()。nextBytes(bytes);
返回org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(bytes);
}



解决方案:::



感谢接受的解决方案,我能够修复我的代码:

  public static boolean authenticate_(String salt,String encryptedPassword,
char [] plainTextPassword)抛出NoSuchAlgorithmException,UnsupportedEncodingException {

//这是好的
字符串saltPlusPlainTextPassword = salt + new String(plainTextPassword);

MessageDigest sha = MessageDigest.getInstance(SHA-512);

//必须指定UTF-8编码
sha.update(saltPlusPlainTextPassword.getBytes(UTF-8));
byte [] hashedByteArray = sha.digest();

//在这里使用Base64编码 - >
String hashed = org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(hashedByteArray);

返回hashed.equals(encryptedPassword);


解决方案

编码会导致您的问题。首先在这里:

  saltPlusPlainTextPassword.getBytes()

这将使用机器的默认编码。馊主意。指定UTF-8作为一个简单的解决方案。 (它保证会出现。)



接下来会导致问题:

  String hashed = new String(hashedByteArray); 

hashedByteArray 是任意的二进制数据。要安全地将其转换为文本,请使用base-64编码或十六进制。同样,您目前正在使用默认编码,每个机器都会有所不同。在Java中有大量第三方库用于base64编码。


I'm having a problem with MessageDigest returning different hash values on different computers.

One computer is running 32-bit Java on Windows Vista and the other is running 64-bit Java on Mac OS. I'm not sure if it is because MessageDigest is machine dependent, or I need to explicitly specify a character encoding somewhere, or perhaps something else. Here's the 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);
}

Should this code execute differently on these two different machines? If it is machine dependent the way I've written it, is there another way hash these passwords that is more portable? Thanks!

Edit:::::

This is the code I'm using to generate the salts:

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:::

Thanks to the accepted solution, I was able to fix my 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);
    }

解决方案

Encodings are causing you problems. First here:

saltPlusPlainTextPassword.getBytes()

That will use the default encoding for the machine. Bad idea. Specify "UTF-8" as a simple solution. (It's guaranteed to be present.)

Next this causes issues:

String hashed = new String(hashedByteArray);

hashedByteArray is arbitrary binary data. To safely convert it to text, either use a base-64 encoding or just hex. Again, you're currently using the default encoding, which will vary from machine to machine. There are loads of 3rd party libraries for base64 encoding in Java.

这篇关于MessageDigest在不同的机器上具有不同的哈希值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆