js实现的加密算法

逆向重点掌握的内容:

1.逆向的思维

2.网站逆向的分析思路和步骤

注意:重点不是放在代码中,而是分析的思路和套路(技巧)

逆向到底是什么?

通俗来讲,逆向就是处理爬虫过程中对于加密数据的破解,和一些动态变化请求参数的处理。

js常见的加密方式

  • 加密在前端开发和爬虫中是经常遇见的。掌握了加密算法且可以将加密的密文进行解密破解的,也是你从一个编程小白到大神级别质的一个飞跃。且加密算法的熟练和剖析也是很有助于帮助我们实现高效的js逆向。下述只把我们常用的加密方法进行总结。不去深究加密的具体实现方式。

  • 常见的加密算法基本分为这几类,

    • 线性散列算法(签名算法)MD5
    • 对称性加密算法 AES DES
    • 非对称性加密算法 RSA

Md5加密(不可逆)

  • MD5是一种被广泛使用的线性散列算法,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整的一致性。且MD5加密之后产生的是一个固定长度(32位或16位)的数据。

    • 结论:一旦看到了一个长度为32位的密文数据,该数据极有可能是通过md5算法进行的加密!
  • 解密:

    • 常规讲MD5是不存在解密的。但是理论上MD5是可以进行反向暴力破解的。暴力破解的大致原理就是用很多不同的数据进行加密后跟已有的加密数据进行对比,由此来寻找规律。理论上只要数据量足够庞大MD5是可以被破解的。但是要注意,破解MD5是需要考虑破解的成本(时间和机器性能)。假设破解当前的MD5密码需要目前计算能力最优秀的计算机工作100年才能破解完成。那么当前的MD5密码就是安全的。
  • 增加破解成本的方法(方法很多,这里只说我常用的)。

    • 使用一段无意义且随机的私匙进行MD5加密会生成一个加密串,我们暂且称之为串1
    • 将要加密的的数据跟串1拼接,再进行一次MD5,这时会生成串2
    • 将串2再次进行MD5加密,这时生成的串3就是我们加密后的数据。
  • 我们在注册账号时的密码一般都是用的MD5加密。

<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 bobo!"); 
		alert(hashCode)
	</script>
		
</html>
  • 上述代码的核心关键字:md5

DES/AES加密(可逆)

crypto-js 是一个纯 javascript 写的加密算法类库 ,可以非常方便地在 javascript 进行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。
GitHub:https://github.com/brix/crypto-js

npm install crypto-js
  • DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的算法。该加密算法是一种对称加密方式,其加密运算、解密运算需要使用的是同样的密钥(一组字符串)即可。
  • 注意:
    • 现在用AES这个标准来替代原先的DES。
    • AES和DES的区别:
      • 加密后密文长度的不同:
        • DES加密后密文长度是8的整数倍
        • AES加密后密文长度是16的整数倍
      • 应用场景的不同:
        • 企业级开发使用DES足够安全
        • 如果要求高使用AES
      • DES和AES切换只需要修改 CryptoJS.AES <=> CryptoJS.DES
  • 使用DES/AES进行数据交互时要求双方都拥有相同的私匙
  • 破解方法:
    • 暴力破解。
    • DES如果使用 56 位的密钥,则可能的密钥数量是 2 的 56 次方个。只要计算足够强大是可以被破解的
  • DES算法的入口参数有三个:
    • Key、Data、Mode,padding。
      • Key为7个字节共56位,是DES算法的工作密钥;
      • Data为8个字节64位,是要被加密或被解密的数据;
      • Mode为DES的工作方式。
      • padding为填充模式,如果加密后密文长度如果达不到指定整数倍(8个字节、16个字节),填充对应字符
        • padding的赋值固定为CryptoJS.pad.Pkcs7即可
<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 = "i am bobo,who are 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); // 0Gh9NGnwOpgmB525QS0JhVJlsn5Ev9cHbABgypzhGnM

		  //解密
		  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); // 我是一个密码
	</script>
		
</html>
  • js中key,iv位数不严格

    • 如何key要求是16位的,但是你给了32位,他会自动截取前面16位;你给了10位,他会自动自动补0
    • 同理如果没给iv 默认 iv=b'0000000000000000'
  • 上述代码的关键字:

    • AES,DES
    • encrypt(用于加密的函数名),decrypt(用于解密的函数名)
    • xxxkey:秘钥一般是单独生成的,一定不会傻到明文的写在代码中!

RSA加密(可逆)

JSEncrypt 是一个用于在浏览器中进行RSA加密和解密的 JavaScript 库。它提供了一种简单的方式来生成 RSA 密钥对、加密数据并使用私钥解密数据。
以下是 JSEncrypt 模块的一些主要功能和用法:

生成密钥对:使用 JSEncrypt,你可以轻松地生成 RSA 密钥对。你可以通过调用 new JSEncrypt() 创建一个 JSEncrypt 实例,然后使用 getKey() 方法生成密钥对。生成的密钥对包括公钥和私钥。
加密数据:一旦你有了密钥对,你可以使用公钥对数据进行加密。使用 JSEncrypt 的 setPublicKey() 方法设置公钥,然后使用 encrypt() 方法对数据进行加密。加密后的数据可以通过网络传输或存储在数据库中。
解密数据:使用私钥可以对加密的数据进行解密。使用 JSEncrypt 的 setPrivateKey() 方法设置私钥,然后使用 decrypt() 方法对加密的数据进行解密。解密后的数据将恢复为原始的明文数据。
密钥格式:JSEncrypt 支持多种密钥格式,包括 PEM 和 DER。你可以使用 getKey() 方法获取生成的密钥对,并使用 getPrivateKey() 和 getPublicKey() 方法获取私钥和公钥的字符串表示。
密钥长度和算法:JSEncrypt 支持不同长度的密钥,包括 1024 位、2048 位和 4096 位。你可以根据需要选择适当的密钥长度。JSEncrypt 使用 RSA 算法进行加密和解密。
兼容性:JSEncrypt 在大多数现代浏览器中都能正常工作,包括 Chrome、Firefox、Safari 和 Edge。它不需要任何其他依赖项,只需引入 JSEncrypt 库即可开始使用。

npm install jsencrypt
  • RSA加密:
    • RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。
  • 非对称加密算法:
    • 非对称加密算法需要两个密钥:
      • 公开密钥(publickey:简称公钥)
      • 私有密钥(privatekey:简称私钥)
      • 公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
  • 注意:
    • 使用时都是使用公匙加密使用私匙解密。公匙可以公开,私匙自己保留。
    • 算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。
  • 使用流程和场景介绍
    • 通过公匙加密,使用私匙解密。私匙是通过公匙计算生成的。假设ABC三方之间相互要进行加密通信。大家相互之间使用公匙进行信息加密,信息读取时使用各自对应的私匙进行信息解密
    • 用户输入的支付密码会通过RSA加密
  • 公钥私钥生成方式:
<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-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyBJ6kZ/VFJYTV3vOC07jqWIqgyvHulv6us/8wzlSBqQ2+eOTX7s5zKfXY40yZWDoCaIGk+tP/sc0D6dQzjaxECAwEAAQ==-----END PUBLIC KEY-----';
        //私钥
		var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvIEnqRn9UUlhNXe84LTuOpYiqDK8e6W/q6z/zDOVIGpDb545NfuznMp9djjTJlYOgJogaT60/+xzQPp1DONrEQIDAQABAkEAu7DFsqQEDDnKJpiwYfUE9ySiIWNTNLJWZDN/Bu2dYIV4DO2A5aHZfMe48rga5BkoWq2LALlY3tqsOFTe3M6yoQIhAOSfSAU3H6jIOnlEiZabUrVGqiFLCb5Ut3Jz9NN+5p59AiEA0xQDMrxWBBJ9BYq6RRY4pXwa/MthX/8Hy+3GnvNw/yUCIG/3Ee578KVYakq5pih8KSVeVjO37C2qj60d3Ok3XPqBAiEAqGPvxTsAuBDz0kcBIPqASGzArumljkrLsoHHkakOfU0CIDuhxKQwHlXFDO79ppYAPcVO3bph672qGD84YUaHF+pQ-----END PRIVATE KEY-----';
		//使用公钥加密
        var encrypt = new JSEncrypt();//实例化加密对象
        encrypt.setPublicKey(PUBLIC_KEY);//设置公钥
        var encrypted = encrypt.encrypt('hello bobo!');//对指定数据进行加密
		alert(encrypted)
        //使用私钥解密
        var decrypt = new JSEncrypt();
        decrypt.setPrivateKey(PRIVATE_KEY);//设置私钥
        var uncrypted = decrypt.decrypt(encrypted);//解密
		alert(uncrypted);
    </script>
</html>
  • 上述代码提取关键字:
    • RSA
    • setPublicKey(设置公钥)
    • setPrivateKey(设置私钥)
    • encrypt,decrypt
  • 只讲这么几个加密算吗吗?
    • 是的。重点是区分加密算法是对称的还是非对称的。
      • 对称秘钥加密:必须要使用秘钥进行加密和解密
      • 非对称的:必须使用公钥加密,私钥解密

base64伪加密

  • Base64是一种用64个字符来表示任意二进制数据的方法。base64是一种编码方式而不是加密算法。只是看上去像是加密而已。
  • Base64使用A--Z,a--z,0--9,+,/ 这64个字符实现对数据进行加密。
<html>
    <script type="text/javascript">
		// 创建Base64对象
		var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9+/=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/rn/g,"n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
		 
		// 定义字符串
		var string = 'i am bobo!';
		 
		// 加密
		var encodedString = Base64.encode(string);
		alert(encodedString); 
		 
		// 解密
		var decodedString = Base64.decode(encodedString);
		alert(decodedString); 
	</script>
		
</html>

  • 对称秘钥加密:
    • 关键字:AES,DES,xxxkey,encrypt,decrypt
    • 核心点:加密和解密环节必须使用同一个秘钥,秘钥获取极为关键!
  • 非对称秘钥加密:
    • 关键字:RSA,setpublickey,setprivatekey,encrypt,decrypt
    • 核心点:加密使用公钥,解密使用私钥。因此公钥和私钥的获取极为重要!
  • 线性散列散发:
    • md5
    • 核心点:加密后不可逆!
posted @ 2022-08-17 17:06  hanfe1  阅读(248)  评论(0编辑  收藏  举报