8-爬虫高级【js逆向】
一、常见的JavaScript加密方式
加密在前端开发和爬虫中是经常遇见的。掌握了加密算法且可以将加密的密文进行解密破解的,也是我们从一个编程小白到大神级别的一个质的飞跃。且加密算法的熟练程度和剖析也是有助于我们实现高效的js逆向。
-
线性散列算法(签名算法)
MD5
-
对称加密算法
AED
DES
-
非对称加密算法
RAS
-
base64
伪加密 -
证书密钥加密
https
加密
二、线性散列算法MD5
1. 概念
MD5
是一种被广泛使用的线性散列算法,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输的一致性。且MD5
加密后产生的是一个固定长度(32位或16位)的数据
2. 解密
常规来讲MD5
是不存在解密的。但是理论上MD5
是可以进行反向暴力破解的。暴力破解的大致原理就是用很多数据进行加密后跟已有的加密数据进行比对,由此来寻找规律。理论上只要数据量足够庞大,MD5
是可以被破解的。但是要注意的是,破解MD5
是需要考虑破解的成本的(时间和机器性能)。假设破解当前的MD5
需要目前计算能力最优秀的的计算机工作100年才能完成破解完成,那么当前的MD5
密码是安全的。
3. 增加解密难度
我们在注册账号时的密码一般都是用
MD5
加密的
- 使用一段无意义且随机的私钥(盐)进行
MD5
加密生成一个加密串(串1) - 将要加密的数据与串1拼接,再进行
MD5
加密生成加密串(串2) - 将串2再次进行
MD5
加密,这是生成的加密串(串3)就是我们加密后的数据
4. js
代码示例
<html>
<script src='https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js'></script>
<script type='text/javascript'>
var hashCode = md5('i am superman');
alert(hashCode); // d5ea627a05a126ce1806a00ee9a3eba1
</script>
</html>
三、对称加密算法DES
/AES
1. 概念
DES
全称Data Encryption Standard,即数据加密标准,是一种使用密钥加密的算法。该加密算法是一种对称加密方式,其加密运算、解密运算需要使用的是同样的密钥(一组字符串)即可。
2. 解密
使用
DES
/AES
进行数据交互时需要双方都拥有相同的私钥
- 暴力破解
DES
如果使用56位的密钥,则可能的密钥数量是2的56次方个。只要计算足够强大是可以被破解的。
3. DES
和AES
的区别
-
加密后的长度不同
DES
加密后密文长度是8的整数倍AES
加密后密文长度是16的整数倍
-
应用场景不同
- 企业级开发使用
DES
足够安全 - 如果要求更高则使用
AES
- 企业级开发使用
-
DES
和AES
进行数据交互时需要双方都拥有相同的私钥
4. DES
算法参数详解
Key、Data、Mode、padding
Key
是7个字节共56位,是DES
算法的工作密钥Data
是8个字节共56位,是要被加密或被解密的数据Mode
是DES
的工作模式padding
是填充模式,如果加密后密文长度达不到指定整数倍(8个字节、16个字节),填充对应字符【padding的复制固定为CryptoJS.pad.Pkcs7
】
5. js
代码示例
<html>
<script src='https://cdn.bootcss.com/crypto-js/3.1.9-1/crypto-js.js'></script>
<script type='text/javascript'>
var aseKey = '12345678'; // 定制私钥,长度必须为8/16/32位
var message = 'how are you? i am fine,and you?';
// 加密 DES/AES切换只需要修改 CryptoJS.AES <=> CryptoJS.DES
var encrypt = CryptoJS.DES.encrypt(message,CryptoJS.enc.Utf8.parse(aseKey), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}).toString();
alert(encrypt); // 加密后的串:zTFKeiIgvJC/zVnJX1uQBUtOMqCHdE00q6e6AtCPvfY=
// 解密
var decrypt = CryptoJS.DES.decrypt(encrypt,CryptoJS.enc.Utf8.parse(aseKey), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}).toString(CryptoJS.enc.Utf8);
alert(decrypt); // 解密后的串:how are you? i am fine,and you?
</script>
</html>
四、非对称加密算法RSA
1. 概念
RSA
加密算法是一种非对称加密算法。在公开密钥解密和电子商业中RSA
算法被广泛使用。非对称加密算法需要两个密钥。
-
公开密钥(
publickey
:简称公钥) -
私有密钥(
privatekey
:简称私钥) -
公钥和私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫做非对称加密算法。
2. 使用流程&应用场景
- 通过公钥加密,使用私钥解密。私钥是通过公钥计算生成的。假设ABC三方之间相互进行加密通信,三人相互之间使用公钥对信息进行加密,信息读取时使用各自对应的私钥进行信息解密
- 用户输入的支付密码会通过
RSA
加密
3. 注意
- 使用时都是用公钥加密数据,用私钥解密数据。公钥是可以公开的,私钥自己保留。
- 算法强度复杂、安全性依赖于算法与密钥,但是由于算法复杂,使得加密解密速度没有对称加密解密速度快。
4. 在线生成RSA
串
http://web.chacuo.net/netrsakeypair/
5. js
代码示例
<html>
<script src='https://cdn.bootcss.com/jsencrypt/3.0.0-beta.1/jsencrypt.js'></script>
<script type='text/javascript'>
// 公钥
var PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD3+A0MhtljS331iaa7Y7dEt9WFJYJdHk+B753nrdMUdOGMGPuWeAekkKLI4cDGEX/sktLTsQullJJvi5+kBXT2hehvaekyraoytkiSmUVjXq2yFSw3j8xjFyK5ye9/suPonA9v/rmDiSy+bnWgsEyikni+Y1yUbcy/f0YX2rJ81wIDAQAB-----END PUBLIC KEY-----';
// 私钥
var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAPf4DQyG2WNLffWJprtjt0S31YUlgl0eT4Hvneet0xR04YwY+5Z4B6SQosjhwMYRf+yS0tOxC6WUkm+Ln6QFdPaF6G9p6TKtqjK2SJKZRWNerbIVLDePzGMXIrnJ73+y4+icD2/+uYOJLL5udaCwTKKSeL5jXJRtzL9/RhfasnzXAgMBAAECgYEAvf360YxI6AGhow4zCAUhGK/aE8hnmD1vIdmcnTTcNCJR5mwF6IZTJM4FS/FdKOWjpHniu3w9tkKd6IWMbboYoIBcfoha5/qZ6IOum8kjimUJXc34ipVl0Y4hwLTNcFg7S3kyA19XeH3Xp+IQ5aizhFx8/aNhFQKPwKEX/vI9OqECQQD/T9D7/yPk+fS5i5q/uduRd9oJoTFKjoFrSpj/1rOZtCGFIwdFi9CtQzvzch/fGAFL580GWbJwJCaUz7py+vrJAkEA+KMq49vCwJABeVT6a6mNCiKB4Qhdkm+yMoA7L1suDnY/CXoitU9OhSkoIcqjthEr/KVYWDxWV+R5d0qSQG3qnwJBAKOZdrXzkQGp9dprjbbrlroJTcs74kT/OgkRXScbYizM02nnv0IeTJKp8aGW8LtZO4NzPtqh4YigcaSL09LX5pkCQFz9sanc5F7evR5i8PHZTP2wYEEIvu5oxg3rNbeFc5lHElZ6DocfLS/Sb8cLoeUTUQ9By+PcVTK0KdW61y4vreMCQQC/vqDH6hvWNjUwdsmwOIOgd9Pgn5UNLKweHf9Mhp0DfmsrWQ6mj66juhsZCP0YvFYUuZ+FSaczINelBh8Ghfhl-----END PRIVATE KEY-----';
// 使用公钥加密
var encrypt = new JSEncrypt(); // 实例化加密对象
encrypt.setPublicKey(PUBLIC_KEY); // 设置公钥
var encrypted = encrypt.encrypt('how are you?'); // 对指定的数据进行加密
alert(encrypted); // Tpe/tER7SjOeDL0IF3SwpnEqLndN7shYqq4J0fchvVonIEJId49g+qSRJg5swYn2Jijc79vr7t1FZZ48Dbs8A88vWPxUifTAImvWRoZm3DZQ8PlGfW0gxdrozcfPmWU1EvduJffkiqnJCei58k2yxY2LapXFDfiXCAkZJQKeWCM=
// 使用私钥解密
var decrtypt = new JSEncrypt();
decrtypt.setPrivateKey(PRIVATE_KEY); // 设置私钥
var uncrypted = decrtypt.decrypt(encrypted); // 解密
alert(uncrypted); // how are you?
</script>
</html>
五、base64
伪加密
1. 概念
base64
是一种用64个字符来表示任意二进制数据的方法。base64
是一种编码方式而不是加密算法。只是看上去像是加密而已
base64
使用A~Z、a~z、0~9、+、/、=
这64个字符实现对数据进行加密。
2. js
代码实现
<html>
<script src='https://cdn.bootcss.com/jsencrypt/3.0.0-beta.1/jsencrypt.js'></script>
<script type='text/javascript'>
// 创建Base64对象(此处不完整)
var Base64 = {
base64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function($input) {
if (!$input) {
return false;
}
var $output = "";
var $chr1, $chr2, $chr3;
var $enc1, $enc2, $enc3, $enc4;
var $i = 0;
do {
$chr1 = $input.charCodeAt($i++);
$chr2 = $input.charCodeAt($i++);
$chr3 = $input.charCodeAt($i++);
$enc1 = $chr1 >> 2;
$enc2 = (($chr1 & 3) << 4) | ($chr2 >> 4);
$enc3 = (($chr2 & 15) << 2) | ($chr3 >> 6);
$enc4 = $chr3 & 63;
if (isNaN($chr2)) $enc3 = $enc4 = 64;
else if (isNaN($chr3)) $enc4 = 64;
$output += this.base64.charAt($enc1) + this.base64.charAt($enc2) + this.base64.charAt($enc3) + this.base64.charAt($enc4);
} while ($i < $input.length);
return $output;
},
decode: function($input) {
if(!$input) return false;
$input = $input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
var $output = "";
var $enc1, $enc2, $enc3, $enc4;
var $i = 0;
do {
$enc1 = this.base64.indexOf($input.charAt($i++));
$enc2 = this.base64.indexOf($input.charAt($i++));
$enc3 = this.base64.indexOf($input.charAt($i++));
$enc4 = this.base64.indexOf($input.charAt($i++));
$output += String.fromCharCode(($enc1 << 2) | ($enc2 >> 4));
if ($enc3 != 64) $output += String.fromCharCode((($enc2 & 15) << 4) | ($enc3 >> 2));
if ($enc4 != 64) $output += String.fromCharCode((($enc3 & 3) << 6) | $enc4);
} while ($i < $input.length);
return $output;
}
};
// 定义字符串
var string = 'how are you?';
// 加密
var encodedString = Base64.encode(string);
alert(encodedString); // aG93IGFyZSB5b3U/
// 解密
var decodedString = Base64.decode(encodedString);
alert(decodedString); // how are you?
</script>
</html>