摘要算法的一些概念
摘自:https://pdai.tech/md/algorithm/alg-domain-security-degist.html
摘要算法简介
消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密
只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文
消息摘要算法主要应用在“数字签名”领域,作为对明文的摘要算法
著名的摘要算法有RSA公司的MD5算法和SHA-1算法及其大量的变体
摘要算法特点
无论输入的消息有多长,计算出来的消息摘要的长度总是固定的
消息摘要看起来是“伪随机的”。也就是说对相同的信息求摘要结果相同
消息轻微改变生成的摘要变化会很大
只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本就找不到任何与原信息相关的信息
摘要算法的应用场景,摘自:https://baike.baidu.com/item/MD5/212708?fr=aladdin
密码管理
电子签名
垃圾邮件筛选
文件完整性校验
常见的摘要算法
常见摘要算法有RSA公司的MD5算法和SHA-1算法及其大量的变体(sha256、sha512)。
可逆和不可逆
可逆通常指的是能对明文数据通过一定的方式进行加密,得到密文数据,然后又可以通过一定的方式来对密文数据进行解密,进而得到原来的明文数据。
而不可逆则是明文数据只能加密成密文数据,而不能对密文数据在解密为原来的明文数据。
这里md5和sha1系列是不可逆的。因为本质上来说,md5、sha1系列实现加密过程是通过hash散列得来的,所以属于摘要算法,不能解密,只不过我们口语中也将md5称为加密算法了。
撞库的概念
撞库是黑客通过收集互联网已泄露的用户和密码信息,生成对应的字典表,尝试批量登录其他网站后,得到一系列可以登录的用户。很多用户在不同网站使用的是相同的帐号密码,因此黑客可以通过获取用户在A网站的账户从而尝试登录B网址,这就可以理解为撞库攻击。
在线破解md5的网站:https://www.cmd5.com/
当然除了md5,包括sha1、sha256等也能撞库成功,为了增加撞库成功的难度,我们通常采用加盐的方式。
加盐
所谓加盐就是,当你有一串非常简单简单的密码123456
生成了md5密文,但该密文被上述网站收录,那么就会很快被撞库成功。但如果我们自己搞一串非常非常非常随机的、一定长度的字符串和你的明文密码一起进行md5加密,那么得到的密文就很难被撞库成功。
加盐在实际开发中,应用非常普遍。
示例
js中使用
下载:
npm install crypto-js
使用:
const CryptoJS = require("crypto-js");
console.log(CryptoJS.MD5('123456').toString()) // 32位 e10adc3949ba59abbe56e057f20f883e
console.log(CryptoJS.SHA1('123456').toString()) // 40位 7c4a8d09ca3762af61e59520943dc26494f8941b
console.log(CryptoJS.SHA256('123456').toString()) // 64位 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
console.log(CryptoJS.SHA512('123456').toString()) // 128位 ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
// 加盐
let SALT = 'django-insecure-%_mn&04vo#bnllm#t@oqfhm__857ybe1yw^@3tw2+ltw+*3u+n'
let code = '123456'
console.log(CryptoJS.MD5(code + SALT).toString()) // 7f345c8d078a0ca01191441e590b0842
html页面中实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>页面中引入md5</h3>
</body>
<!--<script src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.19.0/js/md5.min.js"></script>-->
<script src="./md5.min.js"></script>
<script>
console.log(md5('123456')) // e10adc3949ba59abbe56e057f20f883e
// 加盐
let SALT = 'django-insecure-%_mn&04vo#bnllm#t@oqfhm__857ybe1yw^@3tw2+ltw+*3u+n'
let code = '123456'
console.log(md5(code + SALT)) // 7f345c8d078a0ca01191441e590b0842
</script>
</html>
python实现
# -*- coding = utf-8 -*-
import hashlib
SALT = 'django-insecure-%_mn&04vo#bnllm#t@oqfhm__857ybe1yw^@3tw2+ltw+*3u+n'
code = '123456'
print(hashlib.md5(code.encode('utf-8')).hexdigest()) # 32位 e10adc3949ba59abbe56e057f20f883e
print(hashlib.sha1(code.encode('utf-8')).hexdigest()) # 40位 7c4a8d09ca3762af61e59520943dc26494f8941b
print(hashlib.sha256(code.encode('utf-8')).hexdigest()) # 64位 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
print(hashlib.sha512(code.encode('utf-8')).hexdigest()) # 128位 ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
# 加盐,下面两种写法结果一样,单推荐第一种写法
md = hashlib.md5()
md.update(code.encode('utf-8'))
md.update(SALT.encode('utf-8'))
print(md.hexdigest()) # 7f345c8d078a0ca01191441e590b0842
md2 = hashlib.md5()
code = code + SALT
md2.update(code.encode('utf-8'))
print(md2.hexdigest()) # 7f345c8d078a0ca01191441e590b0842
注意,md5系列使用时,有些注意事项: