乐趣区

关于node.js:NodeJS中与爬虫相关的常见加密

NodeJS 中的 Crypto 应用

在爬虫 JS 解密的时候常常会遇到常见的加密,例如:MD5,Sha1,Sha256,AES,RSA 等加密算法,这些能够在 Python 中调用,当然有时候采纳 NodeJS 调用也很不便,相熟 NodeJS 常见的加密算法对逆向 JS 很有帮忙。NodeJS 中的 Crypto 模块提供了加密性能,包含对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证性能的一整套封装。

Hash

将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规定就是 哈希算法,而通过原始数据映射之后失去的二进制值串就是哈希值(散列值).一个优良的哈希算法须要满足:

  • 从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法);
  • 对输出数据十分敏感,哪怕原始数据只批改了一个 Bit,最初失去的哈希值也大不相同;
  • 散列抵触的概率要很小,对于不同的原始数据,哈希值雷同的概率十分小;
  • 哈希算法的执行效率要尽量高效,针对较长的文本,也能疾速地计算出哈希值。

哈希算法严格来说并不属于加密算法,传统意义上的 加密 是与 解密 相配对的。哈希算法只能加密不能反向解密。

MD5

在 NodeJS 中 MD5 Hash 函数的用法如下:

const crypto = require('crypto');

const hash = crypto.createHash('md5');
console.log(hash.update('666666').digest('hex'))
// f379eaf3c831b04de153469d1bec345e

const hash2 = crypto.Hash('md5');
console.log(hash2.update('666666').digest('hex'))
// f379eaf3c831b04de153469d1bec345e

其中摘要的编码方式有如下三种:

  • latin1
  • hex
  • base64

Sha1

const crypto = require('crypto');
const hash = crypto.createHash('sha1');
console.log(hash.update('666666').digest('hex'))
// 1411678a0b9e25ee2f7c8b2f7ac92b6a74b3f9c5

const hash2 = crypto.Hash('sha1');
console.log(hash2.update('666666').digest('hex'))
// 1411678a0b9e25ee2f7c8b2f7ac92b6a74b3f9c5

Base64

百度百科中对 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 的 ” 加密 ” 与 ” 解密 ”。在浏览器中加密与解密别离对应 btoaatob

Base64 加密

对应浏览器中的 btoa

const data = '666666';
const encodedData = Buffer.from(data, 'utf-8').toString('base64'); // 输出编码为 utf8, 输入为 base64
console.log(encodedData);
// NjY2NjY2

Base64 解密

对应浏览器中的 atob

const data = 'NjY2NjY2';
const decodedData = Buffer.from(data, 'base64').toString('utf8'); // 输出编码为 base64, 输入编码为 utf8
console.log(decodedData);
// 666666

DES

DES 是 Data Encryption Standard(数据加密规范)的缩写。它是由 IBM 公司研制的一种对称明码算法,美国国家标准局于 1977 年颁布把它作为非机要部门应用的数据加密规范,它始终沉闷在国内窃密通信的舞台上,表演了非常重要的角色。

DES 是一个分组加密算法,典型的 DES 以 64 位为分组对数据加密,加密和解密用的是同一个算法。它的密钥长度是 56 位(因为每个第 8 位都用作奇偶校验),密钥能够是任意的 56 位的数,而且能够任意时候扭转。其中有极少数被认为是易破解的弱密钥,然而很容易避开它们不必。所以保密性依赖于密钥。

DES 加解密

const crypto = require('crypto');
const cipher = crypto.createCipheriv('des-cbc', '01234567', '01234567')
var crypted = cipher.update('666666', 'utf8', 'base64');
crypted += cipher.final('base64');
console.log(crypted); // 83OX84xg+iM=

DES 解密

const crypto = require('crypto');
const cipher = crypto.createDecipheriv('des-cbc', '01234567', '01234567')
var crypted = cipher.update('83OX84xg+iM=', 'base64', 'utf8');
crypted += cipher.final('utf8');
console.log(crypted); // 666666

AES

高级加密规范 (AES,Advanced Encryption Standard) 为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用雷同的密钥,具体的加密流程如下图:

AES 加密

const crypto = require('crypto');
const cipher = crypto.createCipheriv('aes128', '0123456789abcdef', '0123456789abcdef')
var crypted = cipher.update('666666', 'utf8', 'hex');
crypted += cipher.final('hex');
console.log(crypted); // c319a2c27be50284fec9fc95d7045737

阐明:

createCipheriv原型如下:

crypto.createCipheriv(algorithm,key,iv [,options])

  1. iv是初始化向量,能够 为空 或者 16 字节的字符串
  2. key是加密密钥,依据选用的算法不同,密钥长度也不同,对应关系如下:

    1. aes128对应 16 位 长度密钥
    2. aes192对应 24 位 长度秘钥
    3. aes256对应 32 位 长度密钥

AES 解密

const crypto = require('crypto');
const cipher = crypto.createDecipheriv('aes128', '0123456789abcdef', '0123456789abcdef')
var data = cipher.update('c319a2c27be50284fec9fc95d7045737', 'hex', 'utf8'); // 输出数据编码为 hex(16 进制),输入为 utf8
data += cipher.final('utf8');
console.log(data); // 666666

RSA

RSA 公开密钥明码体制是一种应用不同的加密密钥与解密密钥,也就是在计算上由已知加密密钥推导出解密密钥是不可行的。
在公开密钥明码体制中,加密密钥(即公开密钥)PK 是公开信息,而解密密钥(即机密密钥)SK 是须要窃密的。加密算法 E 和解密算法 D 也都是公开的。尽管解密密钥 SK 是由公开密钥 PK 决定的,但却不能依据 PK 计算出 SK。
正是基于这种实践,1978 年呈现了驰名的 RSA 算法,它通常是学生成一对 RSA 密钥,其中之一是窃密密钥,由用户保留;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为进步窃密强度,RSA 密钥至多为 500 位长,个别举荐应用 1024 位。这就使加密的计算量很大。为缩小计算量,在传送信息时,常采纳传统加密办法与公开密钥加密办法相结合的形式,即信息采纳改良的 DES 或 IDEA 对话密钥加密,而后应用 RSA 密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核查信息摘要。

RSA 加解密

const crypto = require('crypto');
const {privateKey, publicKey} = crypto.generateKeyPairSync('rsa', {modulusLength: 2048,});
const encodedData = crypto.privateEncrypt(privateKey, Buffer.from('666666','utf8')); // 传入 utf8 编码的数据
console.log(encodedData.toString('hex'));
const rawData = crypto.publicDecrypt(publicKey, Buffer.from(encodedData, 'hex')); // 传入 hex(16 进制)数据
console.log(rawData.toString('utf8'));

总结

常见的加密计划采纳 Python 模块或者 NodeJS 自带的 Crypto 模块就能够解决,然而在工作中还是举荐先扣 JS 加密代码,如果难度比拟大,或者须要耗时,那么就能够采纳 Python 或者 NodeJS 来模仿加密计划。在局部网站中还会有本人创建的算法,这种个别不倡议用 Python 或者 NodeJS 模仿实现,还是间接扣 JS 代码来的不便。

退出移动版