目录
[1. MD5](#1. MD5)
[1.1 JavaScript 实现](#1.1 JavaScript 实现)
[1.2 Python 实现](#1.2 Python 实现)
[2. SHA](#2. SHA)
[2.1 JavaScript 实现](#2.1 JavaScript 实现)
[2.2 Python 实现](#2.2 Python 实现)
[2.3 sha系列特征](#2.3 sha系列特征)
[3. HMAC](#3. HMAC)
[3.1 JavaScript 实现](#3.1 JavaScript 实现)
[3.2 Python 实现](#3.2 Python 实现)
[一. 常见算法归纳](#一. 常见算法归纳)
[1. 工作模式归纳](#1. 工作模式归纳)
[1. ECB模式](#1. ECB模式)
[2. CBC模式](#2. CBC模式)
[3. CFB模式](#3. CFB模式)
[4. OFB模式](#4. OFB模式)
[5. CTR模式](#5. CTR模式)
[6. 总结](#6. 总结)
[二. DES算法](#二. DES算法)
[1. JavaScript 实现](#1. JavaScript 实现)
[2. Python 实现](#2. Python 实现)
基础常识
首先我们需要明白的是,什么是加密和解密?顾名思义 加密(Encryption): 将明文数据变换为密文的过程 解密(Decryption): 加密的逆过程,即由密文恢复出原明文的过程。
加密和解密算法的操作通常都是在一组密钥的控制下进行的,分别成为是加密密钥(Encryption Key)和解密密钥(Decryption Key),如下图所示
而加密算法当中又分为是对称加密和非对称加密以及散列算法,其中
对称加密:即加密与解密时使用的是相同的密钥,例如RC4、AES、DES等加密算法 非对称加密:即加密与解密时使用不相同的密钥,例如RSA加密算法等 散列算法:又称为是哈希函数。对不同长度的输入消息产生固定的输出,该输出值就是散列值
Base64伪加密
Base64严格意义上来说不算做事加密的算法,只是一种编码的方式,它是一种用64个字符,分别是A-Z、a-z、0-9、+、/这64个字符,实现对数据的编码,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。我们使用Python来对任意网址进行Base64的编码操作,代码如下
python代码实现
import base64
# 想将字符串转编码成base64,要先将字符串转换成二进制数据
url = "www.baidu.com"
bytes_url = url.encode("utf-8")
str_url = base64.b64encode(bytes_url) # 被编码的参数必须是二进制数据
print(str_url)
output
b'd3d3LmJhaWR1LmNvbQ=='
那么同样地,我们也可以对其进行解码的操作,代码如下
url = "d3d3LmJhaWR1LmNvbQ=="
str_url = base64.b64decode(url).decode("utf-8")
print(str_url)
摘要算法
在 JavaScript 中和 Python中的基本实现方法,遇到 JS 加密的时候可以快速还原加密过程,有的网站在加密的过程中可能还经过了其他处理,但是大致的方法是一样的。
消息摘要算法/签名算法:MD5、SHA、HMAC
1. MD5
简介:全称MD5 消息摘要算法,又称哈希算法、散列算法,由美国密码学家罗纳德·李维斯特设计,于 1992 年作为 RFC 1321 被公布,用以取代 MD4 算法。摘要算法是单向加密的,也就是说明文通过摘要算法加密之后,是不能解密的。摘要算法的第二个特点密文是固定长度的,它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。之所以叫摘要算法,它的算法就是提取明文重要的特征。所以,两个不同的明文,使用了摘要算法之后,有可能他们的密文是一样的,不过这个概率非常的低。
1.1 JavaScript 实现
地址:汽车之家
安装对应的模块
// 在依赖项中添加包: --save
npm install crypto-js --save
使用案例
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')
function MD5Test() {
var text = "I love python!"
return CryptoJS.MD5(text).toString()
}
console.log(MD5Test())
1.2 Python 实现
import hashlib
def md5_test2():
md5 = hashlib.md5()
md5.update('python'.encode('utf-8'))
print(md5.hexdigest())
if __name__ == '__main__':
md5_test2()
**总结:**MD5哈希视为字符串,而是将其视为十六进制数, MD5哈希长度为128位,通常由32个十六进制数字表示。
2. SHA
简介:全称安全哈希算法,由美国国家安全局(NSA)所设计,主要适用于数字签名标准里面定义的数字签名算法,SHA 通常指 SHA 家族的五个算法,分别是SHA-1、SHA-224、SHA-256、SHA-384、SHA-512,SHA 是比 MD5 更安全一点的摘要算法,MD5 的密文是 32 位,而 SHA-1 是 40 位,版本越强,密文越长,代价是速度越慢。
2.1 JavaScript 实现
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')
function SHA1Encrypt() {
var text = "I love python!"
return CryptoJS.SHA1(text).toString();
}
console.log(SHA1Encrypt())
2.2 Python 实现
import hashlib
def sha1_test2():
sha1 = hashlib.sha1()
sha1.update('I love python!'.encode('utf-8'))
print(sha1.hexdigest())
if __name__ == '__main__':
sha1_test2()
2.3 sha系列特征
sha1:23c02b203bd2e2ca19da911f1d270a06d86719fb
sha224:1ffeffcbe2707dc5d1c10df619203c1a3b620c70394b3c4c106d92e6
sha256:c3a845a318cd654749ea4db6f4d5f9cb5c6e5b0cade46d9dc04af46d32049c7c
sha512:af47f324b77a4885748bfc3f0d9b5a846c0153c589852bb3f185ab6e7a600547b818ab994776e8d24584457f9aac84246b0de971584cebbdd96aa1aee6630f9f
sha1 --》 40
sha224 --》 56
sha256 --》 64
sha512 --》 128
总结:根据长度进行定位、主要还是要去JavaScript里面下断点调试分析
3. HMAC
简介:全称散列消息认证码、密钥相关的哈希运算消息认证码,于 1996 年提出,1997 年作为 RFC 2104 被公布,HMAC 加密算法是一种安全的基于加密 Hash 函数和共享密钥的消息认证协议,它要求通信双方共享密钥 key、约定算法、对报文进行 Hash 运算,形成固定长度的认证码。通信双方通过认证码的校验来确定报文的合法性。
参考资料:
- 百科:hmac_百度百科
3.1 JavaScript 实现
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')
function HMACEncrypt() {
var text = "I love python!"
var key = "secret" // 密钥文件
return CryptoJS.HmacMD5(text, key).toString();
// return CryptoJS.HmacSHA1(text, key).toString();
// return CryptoJS.HmacSHA256(text, key).toString();
}
console.log(HMACEncrypt())
3.2 Python 实现
import hmac
def hmac_test1():
message = 'I love python!'.encode()
key = b'secret'
md5 = hmac.new(key, message, digestmod='MD5')
print(md5.hexdigest())
def hmac_test2():
key = 'secret'.encode('utf8')
sha1 = hmac.new(key, digestmod='sha1')
sha1.update('I love '.encode('utf8'))
sha1.update('Python!'.encode('utf8'))
print(sha1.hexdigest())
if __name__ == '__main__':
hmac_test1() # 9c503a1f852edcc3526ea56976c38edf
hmac_test2() # 2d8449a4292d4bbeed99ce9ea570880d6e19b61a
对称加密
对称加密(加密解密密钥相同):DES、3DES、AES、RC4
简介
对称式加密就是加密和解密使用同一个密钥。信息接收双方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是对数据进行加解密了。对称加密算法用来对敏感数据等信息进行加密。
一. 常见算法归纳
**DES:**56位密钥,由于密钥太短,被逐渐被弃用。
**AES:**有128位、192位、256位密钥,现在比较流行。密钥长、可以增加破解的难度和成本。
1. 工作模式归纳
1. ECB模式
- 全称Electronic Codebook模式,译为电子密码本模式,每个数据块独立进行加/解密
- ECB是最简单的工作模式,原理就是将明文分组,对每一组分别单独加密,加密后的每组密文之间没有联系,在将每一组加密的结果进行拼接
2. CBC模式
- 全称Cipher Block Chaining模式,译为密文分组链接模式
- 这种模式的核心思想是每一个明文分组在被加密之前要与前一个的密文分组进行异或运算,即每一组的加密结果会参与下一个分组的加密,因此第一个分组加密需要有一个初始化向量(IV)参与。
- 最后将每个密文分组按顺序合并起来就得到加密结果
- CBC模式是分组加密中使用最多的模式。
3. CFB模式
- 全称Cipher FeedBack模式,译为密文反馈模式
- 这种工作模式吸收了流加密(流加密可以逐个加密数据,因此适用于流式数据,无需等待整个块加密完成)的特点,可以理解成实现了流加密的CBC 模式
- 加密时,首先对初始化向量(IV)加密,用加密的结果与第一个明文分组异或,得到第一个密文分组
- 然后将此密文分组进行加密(加密前要进行移位处理),将加密结果与第二个明文分组异或
4. OFB模式
- 全称Output Feedback模式,译为输出反馈模式。
- OFB模式与CFB模式类似,区别在于使用上一个分组的密码序列加密生成当前分组的密码序列
5. CTR模式
- 全称Counter模式,译为计数器模式。
- CTR模式与CFB、OFB模式为同一类。但它是通过将逐次累加的计数器进行加密来生成密码序列
- 也就是说,每一个的密文分组是通过将计数器加密得到的密码序列与明文分组进行异或而得到的
6. 总结
二. DES算法
简介:DES 是一种分组加密算法 ,他以64位为分组对数据加密。64位一组的明文从算法的一端 输入,64位的密文从另一端输出。DES是一个对称算法:加密和解密用的是同一个算法(除 密钥编排不同以外)。
密钥的长度为56位(密钥通常表示为64位的数,但每个第8位都用作奇偶检验,可以忽 略)。密钥可以是任意的56位数,且可以在任意的时候改变。
DES 算法的入口参数有3个:Key,Data,Mode。其中Key为8个字节共64位,是DES 算法 的工作密钥;Data也为8个字节64位,是要被加密或解密的数据:Mode为DES的工作方式,有 两种:加密或解密。
DES算法的工作过程:若Mode为加密,则用Key对数据Data进行加密,生成Data的密码 形式(64位)作为DES的输出结果;若Mode为解密,则用Key对密码形式的数据Data解密,还 原为Data的明码形式(64位)作为DES的输出结果。 简单地说,算法只不过是加密的一种基本技术,DES基本组建分组是这些技术的一种组合 ,他基于密钥作用于明文,这是众所周知的轮(round)。DES有16轮,这意味着要在明文分 组上16次实施相同的组合技术。
- mode 支持:CBC,CFB,CTR,CTRGladman,ECB,OFB 等。
- padding 支持:ZeroPadding,NoPadding,AnsiX923,Iso10126,Iso97971,Pkcs7 等。
参考资料:
- RFC 4772:RFC 4772 - Security Implications of Using the Data Encryption Standard (DES)
- DES 维基百科:https://en.wikipedia.org/wiki/Data_Encryption_Standard
1. JavaScript 实现
DES算法的入口参数有3个
- key、DATA、Mode、padding
- key为7个字节共56位,是DES算法的工作密钥
- Data为8个字节64位,是要被加密或被解密的数据
- Mode为DES的工作方式
- padding为填充模式,如果加密后密文长度如果达不到指定整数倍(8个字节,16个字节),填充
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')
function desEncrypt() {
var key = CryptoJS.enc.Utf8.parse(desKey),
iv = CryptoJS.enc.Utf8.parse(desIv),
srcs = CryptoJS.enc.Utf8.parse(text),
// CBC 加密模式,Pkcs7 填充方式
encrypted = CryptoJS.DES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
function desDecrypt() {
var key = CryptoJS.enc.Utf8.parse(desKey),
iv = CryptoJS.enc.Utf8.parse(desIv),
srcs = encryptedData,
// CBC 加密模式,Pkcs7 填充方式
decrypted = CryptoJS.DES.decrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
var text = "I love Python!" // 待加密对象
var desKey = "6f726c64f2c2057" // 密钥
var desIv = "0123456789ABCDEF" // 初始向量
var encryptedData = desEncrypt()
var decryptedData = desDecrypt()
console.log("加密字符串: ", encryptedData)
console.log("解密字符串: ", decryptedData)
// 加密字符串: +ndbEkWNw2QAfIYQtwC14w==
// 解密字符串: I love Python!
2. Python 实现
pip install pyDes
import binascii
# 加密模式 CBC,填充方式 PAD_PKCS5
from pyDes import des, CBC, PAD_PKCS5
def des_encrypt(key, text, iv):
k = des(key, CBC, iv, pad=None, padmode=PAD_PKCS5)
en = k.encrypt(text, padmode=PAD_PKCS5)
return binascii.b2a_hex(en)
def des_decrypt(key, text, iv):
k = des(key, CBC, iv, pad=None, padmode=PAD_PKCS5)
de = k.decrypt(binascii.a2b_hex(text), padmode=PAD_PKCS5)
return de
if __name__ == '__main__':
secret_key = '12345678' # 密钥
text = 'hello world' # 加密对象
iv = secret_key # 偏移量
secret_str = des_encrypt(secret_key, text, iv)
print('加密字符串:', secret_str)
clear_str = des_decrypt(secret_key, secret_str, iv)
print('解密字符串:', clear_str)
# 加密字符串:b'302d3abf2421169239f829b38a9545f1'
# 解密字符串:b'I love Python!'
- 由于库和版本的不同,同样的加密算法在不一样的语言里结果可能不一致,做逆向时最好是选用node来加密网站数据,不使用python来进行加密