这里是修真院后端小课堂,每篇分享文从
【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】
八个方面深度解析后端知识/技能,本篇分享的是:
【什么叫MD5,MD5通常做什么用处,为什么MD5不可逆,用做密码加密的时候仍然可能会被解密?】
标题:
【修真院java小课堂】MD5等常用加密方式的简介
开场语:
大家好,我是IT修真院上海分院第10期的学员许东杰,一枚正直纯洁善良的java程序员,今天给大家分享一下,修真院官网java(职业)任务5,深度思考中的知识点——什么叫MD5,MD5通常做什么用处,为什么MD5不可逆,用做密码加密的时候仍然可能会被解密?
(1)背景介绍:
安全问题已经成为一个越来越重要的问题,在数据的传输过程中如何对重要数据进行加密解密是本课堂的主要内容。
(2)知识剖析:
加密中常见的算法种类及特点:
1、散列函数(hash):用来验证数据完整性的(不是用来加密解密),由于转化不可逆可以用来进行一些验证。常见散列算法:MD5(消息摘要、摘要长度默认128bit)、SHA、MAC(HMAC) 它们的总体安全性是逐步递增的
2、对称加密算法:通过相同密匙进行加密解密,可逆,用来加密解密。常见对称加密算法:DES算法、AED算法
3、非对称加密算法:密匙分为公钥(公开)和私钥(自己保存)。常见非对称加密算法:DH、RSA
加密过程中的两种数据转换:
传入的字符串-->字节数组-->加密过后的字节数组-->转为base64二进制字符进行传输
举例:一个128bit摘要长度的字符串,转为base64二进制字符串是:128/8* (4/3)=22个字符
传入的字符串-->字节数组-->加密过后的字节数组-->转为16进制字符串进行http传输
举例:一个128bit摘要长度的字符串,转为十六进制字符串是:(128/8)*2=32个字符
(3)常见问题:
MD5怎么使用,怎么提高它的安全性
(4)解决方案:
MD5虽然是不可逆的,但是可以通过彩虹码等进行破解
所以为了解决MD5安全性不高的问题,我们采取加盐的方式和HMACMD5(加密匙)方式来使用
(5)编码实战:
MD5加密测试
public class Md5Util {
/**
* 根据输入的字符串生成固定的32位MD5码
*
* @param str
* 输入的字符串
* @return MD5码
*/
public final static String getMd5(String str) {
MessageDigest mdInst = null; //加密实列
try {
mdInst = MessageDigest.getInstance("MD5"); //确定方式
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
mdInst.update(str.getBytes());// 使用指定的字节更新摘要
byte[] md = mdInst.digest();// 获得密文
return StrConvertUtil.byteArrToHexStr(md);
}
}
MD5加随机盐测试
public static String generate(String password) {
Random r = new Random();
StringBuilder sb = new StringBuilder(16);
sb.append(r.nextInt(99999999)).append(r.nextInt(99999999));
int len = sb.length();
if (len < 16) {
for (int i = 0; i < 16 - len; i++) {
sb.append("0");
}
}
String salt = sb.toString();//获取随机数
password = md5Hex(password + salt);//消息摘要
char[] cs = new char[48];
for (int i = 0; i < 48; i += 3) {
cs[i] = password.charAt(i / 3 * 2);
char c = salt.charAt(i / 3);
cs[i + 1] = c;
cs[i + 2] = password.charAt(i / 3 * 2 + 1);//取出password前48位字符组成的数组
}
return new String(cs);//数组转字符串,就是加盐md5消息摘要后的string值
}
//随机盐有两种盐的存放:一种取出放数据库,直接通过算法放到加密后的字符串里面
HMACMD5测试
public static String jdkHmacMD5(String src,String akey) {
try {
KeyGenerator keygenrator = KeyGenerator.getInstance("HmacMD5");
SecretKey secretkey=keygenrator.generateKey();//产生密匙
//byte[] key=secretkey.getEncoded();//获取密匙
byte[] key=akey.getBytes();
SecretKey restore=new SecretKeySpec(key,"HmacMD5"); //还原密匙
Mac mac=Mac.getInstance(restore.getAlgorithm());//实例化mac
mac.init(restore);//初始化
byte[] hmacmd5byte=mac.doFinal(src.getBytes());//执行摘要
//System.out.println(new String(Hex.encodeHex(hmacmd5byte)));
return (new String(Hex.encodeHex(hmacmd5byte)));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
(6)拓展思考:
对称加密算法
DES算法测试
public static String jdkHmacMD5(String src,String akey) {//加入自定义密匙
try {
KeyGenerator keygenrator = KeyGenerator.getInstance("HmacMD5");
SecretKey secretkey=keygenrator.generateKey();//产生密匙
//byte[] key=secretkey.getEncoded();//获取密匙
byte[] key=akey.getBytes();
SecretKey restore=new SecretKeySpec(key,"HmacMD5"); //还原密匙
Mac mac=Mac.getInstance(restore.getAlgorithm());//实例化mac
mac.init(restore);//初始化
byte[] hmacmd5byte=mac.doFinal(src.getBytes());//执行摘要
//System.out.println(new String(Hex.encodeHex(hmacmd5byte)));
return (new String(Hex.encodeHex(hmacmd5byte)));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
AES算法加密测试
public static String encrypt(String content, String password) {
try {
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(byteContent);// 加密
return StrConvertUtil.byteArrToHexStr(result);//通过方法转码返回16进制字符串
} catch (Exception ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
(7)参考文献:
百度、谷歌
(8)更多讨论:
Q1:提问人:为什么要用base64算法?
A1:用64个可打印字符替代所有的二进制字符来进行http网络数据的传递(因为只有那64个可打印字符才能进行http数据传递)
Q2:加密有哪些应用场景
A2:消息摘要用来进行验证消息的完整性 ,也可以进行一些验证(登录验证) ,传递数据,通过和对方共享密匙和算法,就可以对数据进行加密传递。
Q3:提问人:什么是非对称加密?
A3:密匙分为公钥(公开)和私钥(自己保存)。常见非对称加密算法:DH、RSA
(9)鸣谢:
感谢朱明星师兄,此教程是在他们之前技术分享的基础上完善而成。
(10)结束语:
今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。