• Java md5加密 控制台传入与web传入参数 结果不匹配 || 相同字符串加密结果不同,如何保证JAVA MD5加密结果在不同的环境下都相同


    开发中遇到md5加密不一致问题,排除了上下文编码,加密内容问题。

    爬了各类资料,最终找到了原因。

    /** 对字符串进行MD5加密 */
        private static String encodeByMD5(String originString) {
            if (originString != null) {
                try {
                    // 创建具有指定算法名称的信息摘要
                    MessageDigest md = MessageDigest.getInstance("MD5");
                    // 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
                    byte[] results = md.digest(originString.getBytes("UTF-8"));
                    // 将得到的字节数组变成字符串返回
                    String resultString = byteArrayToHexString(results);
                    return resultString.toUpperCase();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            return null;
        }

    需要给加密内容进行指定编码格式获取,对比一下PHP的MD5,真是醉了。

    简单的得出结论: PHP不根据上下文编码格式进行字符的加密。相比于JAVA的加密,是根据加密内容的编码格式进行加密的,需要指定当前上下文对应的编码格式才能获取到想要的加密结果。

    原因示例:

    此类错误通常是编码格式的问题 如果我们控制台输入的字符是 BGK格式的 而 web传入的是UTF-8 我们 toString()查看内容 表明上是看不出区别的 这就导致了相同字符串 加密后得到的结果不同 如下面的小例子

    import static org.apache.commons.codec.digest.DigestUtils.md5Hex; 
    String text = "error606@qq.com|工工工|!@$%&1000"; 
    String r1 = md5Hex(text); // b08f601a7b6b440dfa3ed6eb353c2d24
    String r2 = md5Hex(text.getBytes("UTF-8")); // b08f601a7b6b440dfa3ed6eb353c2d24 
    String r3 = md5Hex(text.getBytes("GBK")); // db9e73be9742ed2a66202a62f491ef03 

    我们再来看一下Java是如何实现MD5的:

    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class MD5Digest {
    
        private static MessageDigest md5=null;
    
        public static String getDigest(String msg) throws UnsupportedEncodingException, NoSuchAlgorithmException {
            if(null == md5) {
                md5=MessageDigest.getInstance("MD5");
            }
            byte[] byteArray=null;
            byteArray=msg.getBytes(); 
            byte[] md5Bytes=md5.digest(byteArray);
            StringBuffer hexValue=new StringBuffer();
            for(int i=0; i < md5Bytes.length; i++) {
                int val=((int)md5Bytes[i]) & 0xff;
                if(val < 16)
                    hexValue.append("0");
                hexValue.append(Integer.toHexString(val));
            }
            return hexValue.toString();
        }
        
        public static void main(String []args) throws UnsupportedEncodingException, NoSuchAlgorithmException{
            System.out.println(getDigest("test测试"));
        }
    }

    通过上面的代码我们会发现一个问题

    byteArray=msg.getBytes();

    在不同的环境下获得的结果可能是不一样的,这样也造成很多MD5结果不一样。

    所以要保证在不同环境下MD5结果相同那么必须使用相同的字符编码,比如:byteArray=msg.getBytes("ISO-8859-1");

    PS:

    http://blog.csdn.net/w627782664/article/details/7064273

  • 相关阅读:
    JavaScript之闭包
    JavaScript之原型模式
    .NET Core3.1 解决跨域问题 Startup的配置
    .NTE Core 使用Editor.md富文本编辑器上传图片
    .NET Core3.1 WebApi 配置Swagger 超详细办法
    C#添加写日志,记录单个变量
    一个让我痛不欲生的算法题
    用EF 搭建底层
    用Linq To SQL 搭建底层
    安卓端腾讯QQ-【我的电脑】下载地址
  • 原文地址:https://www.cnblogs.com/phpdragon/p/4181712.html
Copyright © 2020-2023  润新知