当前位置: 首页 > 后端技术 > Node.js

NodeJS中爬虫相关的常用加密

时间:2023-04-03 17:50:11 Node.js

NodeJS中的Crypto使用了爬虫JS解密时经常遇到的常用加密,例如:MD5、Sha1、Sha256、AES、RSA等加密算法,可以在Python中调用当然,有时候使用NodeJS调用也很方便。熟悉NodeJS常用的加密算法,对逆向JS很有帮助。NodeJS中的Crypto模块提供了加密功能,包括一整套OpenSSL的hash、HMAC、加密、解密、签名、验证功能。哈希将任意长度的二进制值字符串映射为固定长度的二进制值字符串。这种映射的规则是哈希算法,原始数据映射后得到的二进制值字符串就是哈希值(hashvalue)。一个优秀的哈希算法需要满足:原始数据的哈希值不能反推(所以哈希算法也叫单向哈希算法);它对输入的数据非常敏感,即使原始数据只修改了一个Bit,最后得到的哈希值也有很大的不同;哈希冲突的概率应该很小,对于不同的原始数据,哈希值相同的概率很小;哈希算法的执行效率应该尽可能高效,对于较长的文本,也可以快速计算出哈希值。严格来说,哈希算法不是加密算法。传统意义上的加密与解密配对。哈希算法只能加密不能反解密。NodeJS中MD5Hash函数的用法如下:constcrypto=require('crypto');consthash=crypto.createHash('md5');console.log(hash.update('666666').digest('hex'))//f379eaf3c831b04de153469d1bec345econsthash2=crypto.Hash('md5');console.log(hash2.update('666666').digest('hex'))//f379eaf3c831b04de153469d1bec345e摘要有3种编码方式为如下:latin1hexbase64Sha1constcrypto=require('crypto');consthash=crypto.createHash('sha1');console.log(hash.update('666666').digest('hex'))//1411678a0b9e25ee2f7c8b2f7ac92b6a74b3fash.9c5const=crypto('sha1');console.log(hash2.update('666666').digest('hex'))//1411678a0b9e25ee2f7c8b2f7ac92b6a74b3f9c5Base64百度百科对Base64有很好的解释:“Base64是最常见的编码方式之一对于传输8Bit字节码,Base64是一种基于64个可打印字符表示二进制数据的方法。什么是“可打印字符”?为什么要用它来传输8Bit字节码?在回答这两个问题之前,我们有必要思考一下,当我们需要使用Base64?Base64一般用于HTTP协议下传输二进制数据。由于HTTP协议是一种文本协议,因此在HTTP协议下传输二进制数据时,需要将二进制数据转换为字符数据。但是,直接转换是不可能的。因为网络传输只能传输可打印的字符。什么是可打印字符?根据ASCII码,0到31、127共33个字符为控制字符,32到126共95个字符为可打印字符。也就是说,网络传输只能传输这95个字符,不在这个范围内的字符无法传输。那么其他字符如何传输呢?一种方法是使用Base64。Base64是一种使用64个可打印字符表示二进制数据的方法。Base64索引与对应字符的关系如下表所示:更详细的解释请参考:什么是Base64?严格来说,Base64并不是一种加密算法,但是在爬虫中经常会遇到,所以这里介绍下NodeJS中Base64的“加密”和“解密”。浏览器中的加密和解密分别对应btoa和atob。base64加密对应浏览器中的btoa:constdata='666666';constencodedData=Buffer.from(data,'utf-8').toString('base64');//输入编码为utf8,输出为base64console。log(encodedData);//NjY2NjY2Base64解密对应浏览器中的atob:constdata='NjY2NjY2';constdecodedData=Buffer.from(data,'base64').toString('utf8');//输入编码为base64,输出编码为utf8console.log(decodedData);//666666DESDES是DataEncryptionStandard(数据加密标准)的缩写。它是由IBM公司开发的一种对称密码算法。国家标准局于1977年公布为非涉密部门的数据加密标准,一直活跃在国际保密通信的舞台上,发挥了十分重要的作用。角色。DES是一种块加密算法。典型的DES使用64位作为一个块来加密数据。加密和解密使用相同的算法。它的密钥长度为56位(因为每8位用作奇偶校验),密钥可以是任意56位数字,并且可以随时更改。很少有被认为容易破解的弱密钥,但它们很容易避免。所以保密取决于密钥。DES加解密constcrypto=require('crypto');constcipher=crypto.createCipheriv('des-cbc','01234567','01234567')varcrypted=cipher.update('666666','utf8','base64');crypted+=cipher.final('base64');console.log(crypted);//83OX84xg+iM=DES解密constcrypto=require('crypto');constcipher=crypto.createDecipheriv('des-cbc','01234567','01234567')varcrypted=cipher.update('83OX84xg+iM=','base64','utf8');crypted+=cipher.final('utf8');console.log(加密);//666666AES高级加密标准(AES,AdvancedEncryptionStandard)是最常见的对称加密算法(微信小程序加密传输就是采用这种加密算法)。对称加密算法使用相同的密钥进行加密和解密。具体加密过程如下:AES加密constcrypto=require('crypto');constcipher=crypto.createCipheriv('aes128','0123456789abcdef','0123456789abcdef')varcrypted=cipher.update('666666','utf8','hex');crypted+=cipher.final('hex')密码;console.log(加密);//c319a2c27be50284fec9fc95d7045737说明:createCipheriv的原型如下:crypto.createCipheriv(algorithm,key,iv[,options])iv为初始化向量,可以为空或16字节的字符串。key是加密密钥。根据所选算法的不同,密钥的长度也不同。对应关系如下:aes128对应一个16位密钥aes192对应一个24位密钥aes256对应一个32位密钥AES解密constcrypto=require('crypto');constcipher=crypto.createDecipheriv('aes128','0123456789abcdef','0123456789abcdef')vardata=cipher.update('c319a2c27be50284fec9fc95d7045737','hex','utf8');//输入数据编码为hex(十六进制),输出为utf8data+=cipher.final('utf8');控制台日志(数据);//666666RSARSA公钥密码系统使用不同的加密密钥和解密密钥,也就是说,从已知的加密密钥中推导出解密密钥在计算上是不可行的。在公钥密码体制中,加密密钥(即公钥)PK是公开信息,解密密钥(即秘钥)SK需要保密。加密算法E和解密算法D也是公开的。虽然解密密钥SK由公钥PK确定,但不能从PK计算出SK。1978年著名的RSA算法就是基于这个理论出现的。它通常先生成一对RSA密钥,其中一个是秘钥,由用户保管;另一个是公钥,可以对外公开,??甚至可以在网络服务器上注册。为了提高安全强度,RSA密钥长度至少应为500位,一般推荐1024位。这使得加密计算密集。为了减少计算量,在传输信息时,往往采用传统加密方式和公钥加密方式相结合的方式,即用改进的DES或IDEA会话密钥对信息进行加密,然后将会话密钥和信息使用RSA密钥摘要加密。对方收到信息后,可以用不同的密钥解密,查看信息摘要。RSA加解密constcrypto=require('crypto');const{privateKey,publicKey}=crypto.generateKeyPairSync('rsa',{modulusLength:2048,});constencodedData=crypto.privateEncrypt(privateKey,Buffer.from('666666','utf8'));//传入utf8编码的数据console.log(encodedData.toString('hex'));constrawData=crypto.publicDecrypt(publicKey,Buffer.from(encodedData,'hex'));//传入hex(十六进制)数据console.log(rawData.toString('utf8'));总结常见的加密方案可以使用Python模块或者NodeJS自带的Crypto模块来解决,但是在工作中还是建议先扣除JS加密代码。如果比较困难或者比较费时,那么可以使用Python或者NodeJS来模拟加密方案。有些网站也有自己的算法,一般不建议用Python或者NodeJS模拟,直接扣JS代码比较方便。