JS逆向常用加解密算法

1,064 阅读5分钟

本篇文章将介绍JS逆向常见的加密算法

1.消息摘要算法

常见的消息摘要算法有MD5 | sha1 | sha256 | sha512

什么是消息摘要算法呢?

消息摘要算法又叫单向散列函数。消息摘要算法的特点是,对于不同的明文,加密后的结果值是唯一且是定长的,加密算法不可逆(也就是说无法根据密文解密得到明文)

举个例子:我们在网上都会输入账号密码。这个时候就可以对密码进行一个MD5加密。具体的算法实现逻辑并不需要我们实现,我们可以使用一些加密库 如:crypto-js

安装加密库

npm install crypto-js

md5加密,示例代码

const CryptoJs = require('crypto-js');

// MD5加密
let password = "123456";
let encPwd = CryptoJs.MD5(password).toString();
console.log(encPwd);  // e10adc3949ba59abbe56e057f20f883e

sha1加密算法,示例代码

const CryptoJs = require('crypto-js');\
// MD5加密
let password = "123456";
let encPwd = CryptoJs.SHA1(password).toString();
console.log(encPwd);  // 7c4a8d09ca3762af61e59520943dc26494f8941b

我们再来理解一下,什么叫加密算法不可逆,就是即使我们得到密文数据e10adc3949ba59abbe56e057f20f883e,我们也没办法解密。后端拿到密文数据之后,是将明文数据采用相同算法加密,再将加密后的结果与提交上来的数据进行比对。如果一致,那么密码正确。网上一些MD5破解也是相同的道理,实际上是将明文数据加密后再和密文比对。因为对于相同一段明文,加密结果是唯一的。

2.对称加密算法

常见的对称加密算法有AES | DES | TripleDES

什么叫对称加密算法呢?对称加密算法就是使用密钥对明文进行加密,使用加密的密钥对密文进行解密。对称加密算法是可逆的。也就是说,如果我们得到一段密文数据,如果能够获取到加密的密钥,那么我们就能对密文数据进行解密。

下面介绍AES加密算法

AES加密算法,示例代码

// AES加密

let password = "123456";

let key = "1234567890abcdef"

cfg = {
 modeCryptoJs.mode.ECB,
 paddingCryptoJs.pad.Pkcs7
}
let encPwd = CryptoJs.AES.encrypt(password, key, cfg).toString()

console.log(encPwd)  // U2FsdGVkX1+meKI+IXd44qgc50bKb2rDbN91OutwBWs=

一共需要传递三个参数,分别是password | key 以及 cfg配置模式

根据密钥长度的不同, 可以把AES加密算法分为AES-128/AES-192/AES-256。也就是说密钥的长度必须是16/24/32个字节

mode模式常用的有 CBC | ECB两种

这两种模式的区别在于是否需要配置iv向量

使用CBC模式进行加密示例代码如下:

const CryptoJs = require('crypto-js');
// AES加密

let password = CryptoJs.enc.Utf8.parse("123456")  // 指定以什么编码方式解析明文
let key = CryptoJs.enc.Utf8.parse("1234567890abcdef")
let iv = CryptoJs.enc.Utf8.parse("123456")  // 需指定初始向量

cfg = {
 modeCryptoJs.mode.CBC,
 paddingCryptoJs.pad.Pkcs7,
 iv: iv
}

let encPwd = CryptoJs.AES.encrypt(password, key, cfg).toString()\
console.log(encPwd)

填充模式常用的有三种, 分别是NoPadding | ZeroPadding | Pkcs7

默认的填充方式是Pkcs7

既然是对称加密算法,那么如果拿到密文数据,是可以对其进行解密的。只需要拿到加密的密钥。

AES解密示例代码如下

// AES解密
let key = CryptoJs.enc.Utf8.parse("1234567890abcdef")

cfg = {
 modeCryptoJs.mode.ECB,
 paddingCryptoJs.pad.Pkcs7
}

encPwd = "5npjufQ0AT0RkEDe6Rcnsw=="

decPwd = CryptoJs.AES.decrypt(encPwd, key, cfg).toString(CryptoJs.enc.Utf8// 指定解码方式
console.log(decPwd)  // 123456

DES和AES的用法相似,这里就不再赘述。

DES加解密示例代码如下

const CryptoJs = require('crypto-js');
// DES加密
let password = CryptoJs.enc.Utf8.parse("123456")  // 指定以什么编码方式解析明文

let key = CryptoJs.enc.Utf8.parse("1234567")

cfg = {
 modeCryptoJs.mode.ECB,
 paddingCryptoJs.pad.Pkcs7
}

let encPwd = CryptoJs.DES.encrypt(password, key, cfg).toString()
console.log(encPwd)  // N2QgeYj8vBU=

// DES解密
decPwd = CryptoJs.DES.decrypt(encPwd, key, cfg).toString(CryptoJs.enc.Utf8// 指定解码方式
console.log(decPwd) // 123456

3.非对称加密算法

常用的非对称加密算法有RSA,什么是非对称加密算法呢?对称加密算法,我们使用的是同一个密钥,而非对称加密算法有公钥和私钥。公钥加密,私钥解密。crypto-js并不支持RSA算法。所以如果想要在node中使用RSA算法做加密,我们需要安装另一个加密库jsencrypt

安装jsencrypt

npm install jsencrypt

RSA加解密示例代码如下:

公钥和私钥需要生成,这里我们使用在线生成方式

加解密网址:web.chacuo.net/netrsakeypa…

生成RSA密钥对 生成RSA密钥对

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnX3j/luQG7JnPFIFJKEvPC/tF
tv14XIzT7FQXYpKsOt2t4uLh6hZa5H5WcEinF46nc91UbrS5UA9Fnnm+Ev20pwUE
PVu4On47am6vJOsq8oqQoZDsMu6VGZIzKIm8vDylO6I2xrTaXY2G3hdiRKF7988t
A4oYsFOTZ/yG/BOlNwIDAQAB
-----END PUBLIC KEY-----

-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKdfeP+W5Absmc8U
gUkoS88L+0W2/XhcjNPsVBdikqw63a3i4uHqFlrkflZwSKcXjqdz3VRutLlQD0We
eb4S/bSnBQQ9W7g6fjtqbq8k6yryipChkOwy7pUZkjMoiby8PKU7ojbGtNpdjYbe
F2JEoXv3zy0DihiwU5Nn/Ib8E6U3AgMBAAECgYA6KW0stEytM08HrQJ4X65oVquM
wFg4mUC+7CMUtUZu303lfTCGfQgjsb9NXluA5SjHe/Xvv0DCHNYRxU5dBNBwhIXa
RLy6zLKKKp/0gOn1C3dFY/MQOVoEpJ8uxUQh9Kf37F5J9gT64JNooKTTNydqTcmf
IhG/u3WFiTVjfW5sEQJBANmvAgUneA6eEC6LwhX9gxdp0T2S+hop19zAm4ErHQld
47TlSAxVgwArQG4oJ5J2OWlIT4vzuO1OJOaCj4wZYXMCQQDE1W0uZA1YtjVK7OUu
D3f/rgNzolpc0XEEZDPxKsoirEFgW/cFNCTJKIdGK2RgnthLWiN01a9bL6+sF2vL
O2wtAkAd0h3Cuv91cS3iUn8KKCqXQIXLm6DriKPrt+8VqORXbidNlsNh/SzvDv3K
mXGiXNPMmn1bPM4upC/l7CjiFnAFAkBnmu+dO4zK5R2oEomPdRT0v+OROiPWN2gF
p7iveJZtKb4/uiiL1KaIO4z4ol5zfSjcgNWo6dEjbjZJnwpeLykBAkAY/tYLGyrH
e0isoZL2xXPlrvde2tbKcbzMrheH1wuqEMX0o0+uHCyFgn2rAzMcfUlntb9iZLLJ
DkJ+bFET1j3l
-----END PRIVATE KEY-----

RSA加解密

window = global

const JSEncrypt = require('jsencrypt')

publickey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnX3j/luQG7JnPFIFJKEvPC/tFtv14XIzT7FQXYpKsOt2t4uLh6hZa5H5WcEinF46nc91UbrS5UA9Fnnm+Ev20pwUEPVu4On47am6vJOsq8oqQoZDsMu6VGZIzKIm8vDylO6I2xrTaXY2G3hdiRKF7988tA4oYsFOTZ/yG/BOlNwIDAQAB'

// 加密
let jse = new JSEncrypt()
jse.setPublicKey(publickey)
var encStr = jse.encrypt('username')
console.log("加密数据: " + encStr)

// 解密
privatekey = 'MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKdfeP+W5Absmc8UgUkoS88L+0W2/XhcjNPsVBdikqw63a3i4uHqFlrkflZwSKcXjqdz3VRutLlQD0Weeb4S/bSnBQQ9W7g6fjtqbq8k6yryipChkOwy7pUZkjMoiby8PKU7ojbGtNpdjYbeF2JEoXv3zy0DihiwU5Nn/Ib8E6U3AgMBAAECgYA6KW0stEytM08HrQJ4X65oVquMwFg4mUC+7CMUtUZu303lfTCGfQgjsb9NXluA5SjHe/Xvv0DCHNYRxU5dBNBwhIXaRLy6zLKKKp/0gOn1C3dFY/MQOVoEpJ8uxUQh9Kf37F5J9gT64JNooKTTNydqTcmfIhG/u3WFiTVjfW5sEQJBANmvAgUneA6eEC6LwhX9gxdp0T2S+hop19zAm4ErHQld47TlSAxVgwArQG4oJ5J2OWlIT4vzuO1OJOaCj4wZYXMCQQDE1W0uZA1YtjVK7OUuD3f/rgNzolpc0XEEZDPxKsoirEFgW/cFNCTJKIdGK2RgnthLWiN01a9bL6+sF2vLO2wtAkAd0h3Cuv91cS3iUn8KKCqXQIXLm6DriKPrt+8VqORXbidNlsNh/SzvDv3KmXGiXNPMmn1bPM4upC/l7CjiFnAFAkBnmu+dO4zK5R2oEomPdRT0v+OROiPWN2gFp7iveJZtKb4/uiiL1KaIO4z4ol5zfSjcgNWo6dEjbjZJnwpeLykBAkAY/tYLGyrHe0isoZL2xXPlrvde2tbKcbzMrheH1wuqEMX0o0+uHCyFgn2rAzMcfUlntb9iZLLJDkJ+bFET1j3l'
jse.setPrivateKey(privatekey)
var Str = jse.decrypt(encStr)
console.log("解密数据: " + Str)