首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生成MD5哈希

生成MD5哈希
EN

Stack Overflow用户
提问于 2013-07-30 12:16:48
回答 3查看 3.6K关注 0票数 0

我有一个发送给我的密码,它使用AES加密,并基于数字ID使用MD5哈希进行加密。

从请求中,我可以使用其他属性获取数据库中的id,因此在服务器端,我需要获取id,基于该id获取MD5哈希,并使用AES算法和生成的MD5哈希来解密密码。

我使用以下代码获取MD5哈希

代码语言:javascript
复制
 try {
        byte[] bytesOfMessage = id.getBytes("UTF-8");
        log.error "bytesOfMessage length: " + bytesOfMessage.length
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] thedigest = md.digest(bytesOfMessage);

        md5Value = new String(thedigest);
        log.error "md5Value length: " + md5Value.length()
        log.error "md5Value bytes length: " + md5Value.getBytes().length
    } catch (UnsupportedEncodingException e) {
        log.error "[getMD5EncryptionKey]UnsupportedEncodingException: " + e;
    } catch (NoSuchAlgorithmException e) {
        log.error "[getMD5EncryptionKey]NoSuchAlgorithmException: " + e;
    }

基于id为1的md5value长度为16,但是当我从这个md5Value获得字节时,有34个字节

当我使用这个MD5哈希和javax.crypto.Cipher库解密密码时,我得到以下消息

java.security.InvalidKeyException:无效的AES密钥长度: 34字节

知道我在这里做错了什么吗?

用于解密消息的代码如下所示

代码语言:javascript
复制
  try {
        byte [] encryptionKeyBytes = md5EncryptionKey.getBytes("UTF-8");
        Key key = new SecretKeySpec(encryptionKeyBytes, "AES");
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decodedValue = new Base64().decode(encryptedData);
        byte[] decValue = c.doFinal(decodedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    } catch (InvalidKeyException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (IllegalBlockSizeException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (BadPaddingException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (NoSuchAlgorithmException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (NoSuchPaddingException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (Exception e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-30 12:43:06

字符串是十六进制的问题。我建议您使用包。这里有一个用于散列的实用程序类。

http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html

然后可以使用以下代码:

代码语言:javascript
复制
String md5 = DigestUtils.md5Hex(id);
// or
byte[] md5 = DigestUtils.md5(id);
票数 1
EN

Stack Overflow用户

发布于 2013-07-30 12:23:25

得到的字节数组是一个MD5-散列,但带有十六进制值。

您不能只是将数组转换为字符串。您必须使用一个算法来转换它,该算法接受那些十六进制值,并给出正确的字符串。

下面您可以看到一个获得32位MD5哈希字符串的算法,也许这会有所帮助:

代码语言:javascript
复制
public String createHashString(String s)
{

    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytesOfMessage = s.getBytes("UTF-8");
        byte[] thedigest = md.digest(bytesOfMessage);


        String hexString = "";
        for(byte bi : thedigest)
        {
            String hex = Integer.toHexString(0xFF & bi);
            if (hex.length() == 1) {

                hexString += "0";
            }
            hexString += (hex);
        }

        return hexString;

    } 
    catch (Exception e) {
        return "";
    }
}
票数 1
EN

Stack Overflow用户

发布于 2013-07-30 12:26:57

这个md5Value = new String(thedigest)是你的问题。thedigest是二进制的,String类无法确定它的编码(因为它没有),这会导致二进制值在试图从字符串中取出时受到破坏。这就是为什么md5Value.getBytes().length是34个字节的原因。直接从SecretKeySpec创建thedigest

代码语言:javascript
复制
Key key = new SecretKeySpec(thedigest, "AES");

AES键需要是MD5哈希的实际16字节二进制值。

注意,new String(someBinaryByteArray).getBytes()有时会返回与您输入的字节相同的字节,但这都取决于输入。您的输入id值说明了这一点。另一个例子是:

代码语言:javascript
复制
String id = "test";
byte[] bytesOfMessage = id.getBytes("UTF-8");
System.out.println("bytesOfMessage length: " + bytesOfMessage.length);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
System.out.println("thedigest Hex: " + Hex.encodeHexString(thedigest));
String md5Value = new String(thedigest);
System.out.println("md5Value length: " + md5Value.length());
System.out.println("md5Value bytes length: " + md5Value.getBytes().length);
System.out.println("md5Value Hex: " + Hex.encodeHexString(md5Value.getBytes()));

Output:
bytesOfMessage length: 4
thedigest Hex: 098f6bcd4621d373cade4e832627b4f6
md5Value length: 16
md5Value bytes length: 16
md5Value Hex: 093f6bcd4621d373cade4e832627b4f6

098f6bcd4621d373cade4e832627b4f6 != 093f6bcd4621d373cade4e832627b4f6

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17946810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档