首页 > 编程知识 正文

md5加密算法的基本原理,简单介绍MD5加密算法

时间:2023-05-03 18:48:16 阅读:273999 作者:3469

目录

 

1.MD5简介;

2.MD5用途;

3.MD5工具类的实现;

4.MD5加密过程;

5. MD5特征分析;


​​​​​​​ 1.MD5简介;

MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

密码散列函数(Cryptographic hash function),又译为加密散列函数,是散列函数的一种。它被认为是一种单向函数,也就是说极其难以由散列函数输出的结果,回推输入的数据是什么。这样的单向函数被称为“现代密码学的驮马”。这种散列函数的输入数据,通常被称为消息(message),而它的输出结果,经常被称为消息摘要(message digest)或摘要(digest)。在信息安全中,有许多重要的应用,都使用了密码散列函数来实现,例如数字签名,消息认证码。 

 

2.MD5用途;

 MD5特点:用户传入一个明文的字符串,加密后得到一个密文!

 

3.MD5工具类的实现;

加盐方式:

//加盐方式 public static String EncoderPwdByMd5(String pwd) throws NoSuchAlgorithmException { // 1,获取信息摘要对象md5,利用其单例函数来获取 MessageDigest md5=MessageDigest.getInstance("MD5"); // 2,信息摘要对象md5是对字节数组进行摘要的,所以先获取字符串的字节数组 byte[] str_bytes=pwd.getBytes(); // 3,信息摘要对象对得到的字节数组进行摘要,得到摘要字节数组,返回的是byte[] - 字节数组,长度是16个字节 byte[] result = md5.digest(str_bytes); // 4,把摘要数组中的每一个字节转换成16进制,并拼在一起就得到了MD5值. StringBuffer sb = new StringBuffer(); // 把每一个byte 做一个与运算 0xff; for (byte b : result) { // 与运算,获取字节的低8位有效值 int number = b & 0xff;// 加盐 // 将整数转换成16进制 String str = Integer.toHexString(number); // 如果是1位的话,补0 if (str.length() == 1) { sb.append("0"); } // 把密文添加到缓存中 sb.append(str); } // 标准的md5加密后的结果 return sb.toString(); }

主函数测试:

public static void main(String[] args) throws NoSuchAlgorithmException { System.out.println("加密后的密码为:n"+EncoderPwdByMd5("123fbuinnviuiwj265")); System.out.println("md5密文的位数:n"+EncoderPwdByMd5("123").length()); }

运行结果:

 

普通方式:

//普通方式 public static String EncoderPwdByMd5_2(String pwd) throws NoSuchAlgorithmException { char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; // 1,获取MD5摘要算法的MessageDigest对象md5,利用其单例函数来获取MD5的对象 MessageDigest md5=MessageDigest.getInstance("MD5"); // 2,将密码先转换成字节数,使用指定的字节更新摘要 md5.update(pwd.getBytes()); // 3,获得密文 byte[] result = md5.digest(); // 4,把密文(字节数组)转换成十六进制的字符串形式,拼在一起就得到了MD5值 int j = result.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = result[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); }

主函数测试:

public static void main(String[] args) throws NoSuchAlgorithmException { //System.out.println("加密后的密码为:n"+EncoderPwdByMd5("123fbuinnviuiwj265")); //System.out.println("md5密文的位数:n"+EncoderPwdByMd5("123").length()); System.out.println("加密后的密码为:n"+EncoderPwdByMd5_2("123")); System.out.println("md5密文的位数:n"+EncoderPwdByMd5("123").length()); }

运行结果:

 

4.MD5加密过程;

加密过程分为4步:

第1步:

//1,获取MD5摘要算法的MessageDigest类,利用其单例函数来获取对象md5MessageDigest md5=MessageDigest.getInstance("MD5");

第2步:

/*2,信息摘要的方法md5.digest(),其中的参数和返回值都是byte[](字节数组)类型;所以先要获取字符串的字节数组;*/ byte[] str_bytes=pwd.getBytes();

第3步:

/*3,信息摘要对象对得到的字节数组进行摘要,得到摘要字节数组,返回的是byte[] - 字节数组,长度是16个字节*/byte[] result = md5.digest(str_bytes);

第4步:

// 4,把摘要数组中的每一个字节转换成16进制,并拼在一起就得到了MD5值StringBuffer sb = new StringBuffer(); // 把每一个byte 做一个与运算 0xff; for (byte b : result) { // 与运算,获取字节的低8位有效值 int number = b & 0xff; // 将整数转换成16进制 String str = Integer.toHexString(number); // 如果是1位的话,补0 if (str.length() == 1) { sb.append("0"); } // 把密文添加到缓存中 sb.append(str); } // 标准的md5加密后的结果 return sb.toString();

 

5. MD5特征分析;

总体概括:

用户传入一个明文的字符串(可见),加密后得到一个密文(不可见)!

得到的散列值特点: 

1,密文为128bit(16字节)的散列值,用于确保信息传输完整一致

2,长度固定,不管多长的字符串,加密后长度都是一样长;

3,不可逆,你明明知道密文和加密方式,你却无法反向计算出原密码,一般解密不了;

长度问题:

1,md5的长度,默认为128bit,也就是128个0和1的二进制串;

2,格式不太好,所以将二进制转成了16进制,每4个bit表示一个16进制,

3,所以128/4 = 32 换成16进制表示后,为32位了;

byte类型转换成int类型:

首先byte是1个字节,8bit;

int是4个字节,32bit;

当把一个低精度的数据类型转成一个高精度的数据类型时,必然会涉及到如何扩展位数的问题;

补符号位扩展,若为负数,高24位全部补1,转换成十进制则会出问题。

目的就是为了保证二进制数据的一致性。

 第一,oxff默认为整形,二进制位最低8位是1111  1111,前面24位都是0;

第二,&运算: 如果2个bit都是1,则得1,否则得0;

第三,byte的8位和0xff进行&运算后,最低8位中,原来为1的还是1,原来为0的还是0,而0xff其他位都是0,所以&后仍然得0,

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。