MD5加密详解
来源:互联网 发布:免费扫描软件 编辑:程序博客网 时间:2024/06/06 16:49
【1】MD5是什么
Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992)
。
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。
MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等。
对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
128位散列值转换为16进制字符串为32位。即,加密后的结果为32位16进制的字符串。
【2】MD5的特点
① 长度固定
不管多长的字符串,加密后长度都是一样长,方便平时信息的统计和管理。
② 容易计算
从原数据计算出MD5值很容易。
③ 抗修改性
对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
④ 强抗碰撞
已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的(并非不可以)。
【3】MD5加密过程
第一种,加密字符串
① 获取信息摘要对象:md5
通过信息摘要单例的构造函数获取:
MessageDigest md5 = MessageDigest.getInstance("MD5");
② 获取摘要字节数组
两种方式:
byte[] bytes = str.getBytes();byte[] digest = md5.digest(bytes);或byte[] bytes = str.getBytes();md5.update(bytes);byte[] digest = md5.digest();
③ 把摘要数组中的每一个字节转换成16进制,并拼在一起就得到了MD5值.
第二种,加密文件
方法传入的是文件对象 : file
① 因为是文件不是方法,所以不是像刚才那样通过摘要获取字符串。
② 使用到另一个方法即可:就是信息摘要对象更新:md5.update(byte[] input)方法,用法是通过读取流,不断的更新从流中读到的”信息数组”。
③ 然后通过”信息摘要对象”获取摘要,不用参数:md5.digest(),此时返回的数组就已经是包含内容的摘要数组了。
④ 把摘要数组中的每一个字节转换成16进制,并拼在一起就得到了MD5值。
同样来源除了文件还可以是url,过程同上。
【4】MD5工具类
package com.web.encrypt;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.math.BigInteger;import java.net.HttpURLConnection;import java.net.URL;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5Util { private static char hexDigits[] = { // 用来将字节转换成 16 进制表示的字符 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd','e', 'f' }; protected static MessageDigest messagedigest = null; static { try { messagedigest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException nsaex) { System.err.println(MD5Util.class.getName() + "初始化失败,MessageDigest不支持MD5Util。"); nsaex.printStackTrace(); } } // 加密字符串 public static String getMD5(String str){ byte[] bs = str.getBytes(); return getMD5FromByte(bs); } private static String getMD5FromByte(byte[] source) { String s = null; try { java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); md.update(source); byte tmp[] = md.digest(); // MD5 的计算结果是一个 128 位的长整数,用字节表示就是 16 个字节 char str[] = new char[16 * 2]; // 每个字节用 16 进制表示的话,使用两个字符,所以表示成 16 进制需要 32 个字符 int k = 0; // 表示转换结果中对应的字符位置 for (int i = 0; i < 16; i++) { // 从第一个字节开始,对 MD5 的每一个字节 // 转换成 16 进制字符的转换 byte byte0 = tmp[i]; // 取第 i 个字节 str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字节中高 4 位的数字转换,>>>为逻辑右移,将符号位一起右移 str[k++] = hexDigits[byte0 & 0xf]; // 取字节中低 4 位的数字转换 } s = new String(str); // 换后的结果转换为字符串 } catch (Exception e) { e.printStackTrace(); } return s; } // 加密文件对象 public static String getFileMD5String(File file) throws FileNotFoundException { String value = null; FileInputStream in = new FileInputStream(file); try { MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(byteBuffer); BigInteger bi = new BigInteger(1, md5.digest()); value = bi.toString(16); } catch (Exception e) { e.printStackTrace(); } finally { if(null != in) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return value; } //参数为文件路径 public static String getFileMD5String(String filePath) throws FileNotFoundException { String value = null; File file=new File(filePath); FileInputStream in = new FileInputStream(file); try { MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(byteBuffer); BigInteger bi = new BigInteger(1, md5.digest()); value = bi.toString(16); } catch (Exception e) { e.printStackTrace(); } finally { if(null != in) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return value; } //参数为url public static String getFileMD5StringByURL(String urlString) throws IOException { URL url = new URL(urlString); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); BufferedInputStream fis = null; fis = new BufferedInputStream(connection.getInputStream()); byte[] buffer = new byte[1024]; int numRead = 0; while ((numRead = fis.read(buffer)) > 0) { messagedigest.update(buffer, 0, numRead); } fis.close(); return bufferToHex(messagedigest.digest()); } //参数为字节数组 public static String getMD5String(byte[] bytes) { messagedigest.update(bytes); return bufferToHex(messagedigest.digest()); } // 将字节数组转换为16进制的字符串 private static String bufferToHex(byte bytes[]) { int m = 0; int n = bytes.length; StringBuffer stringbuffer = new StringBuffer(2 * n); int k = m + n; for (int l = m; l < k; l++) { appendHexPair(bytes[l], stringbuffer); } return stringbuffer.toString(); } private static void appendHexPair(byte bt, StringBuffer stringbuffer) { char c0 = hexDigits[(bt & 0xf0) >> 4]; // 取字节中高 4 位的数字转换, >>> 为逻辑右移,将符号位一起右移 char c1 = hexDigits[bt & 0xf]; // 取字节中低 4 位的数字转换 stringbuffer.append(c0); stringbuffer.append(c1); }}
- md5加密技术详解
- MD5加密详解
- MD5加密详解
- Java MD5 VS SAH 加密方法详解
- MD5加密及’解密‘ 验签详解
- IOS之sha加密、md5常规加密、md5二次加密详解及示例程序
- IOS之sha加密、md5常规加密、md5二次加密详解及示例程序
- IOS之sha加密、md5常规加密、md5二次加密详解及示例程序
- IOS之sha加密、md5常规加密、md5二次加密详解及示例程序
- IOS之sha加密、md5常规加密、md5二次加密详解及示例程序
- MD5加密
- MD5加密
- md5加密
- MD5加密
- md5加密
- MD5加密
- MD5加密
- md5 加密
- Wireshark学习笔记——如何快速抓取HTTP数据包
- 关于如何修改CSDN中的字体大小和颜色
- ACM-ICPC北京赛区2017网络同步赛(题目6 : Secret Poems)
- C/汇编的混合编程
- 关于程序
- MD5加密详解
- 安卓的那些事儿-android之RecyclerView的使用,实现列表横向滚动
- C++中变量的作用域
- 机器学习(神经网络)
- [BZOJ1007][HNOI2008]水平可见直线(栈)
- 微信测试账号(验证成为开发者)总是配置失败
- 树-堆结构练习——合并果子之哈夫曼树
- Netty学习(一)—基本使用
- crontab定时任务不执行,单独运行sh生效