前端加密的方法及node 的crypto 使用

加密是确保数据安全、保护隐私、遵守法律法规的关键技术。它不仅在传输过程中保护数据免受窥探,还确保数据在存储和处理时的安全性,并防止数据被篡改或滥用。因此,现代互联网和通信系统中的加密技术至关重要。

1、哈希算法

在这里插入图片描述

哈希(Hash)是一种将任意长度的输入(如字符串、文件等)通过哈希函数转换为固定长度输出的过程。输出通常称为哈希值或摘要

哈希加密的主要场景就是 密码存储、大文件分片上传验证文件完整性

特点

  1. 确定性:相同的输入总是产生相同的哈希值
  2. 高效性:计算哈希值的过程应快速完成。
  3. 抗碰撞性:难以找到两个不同的输入产生相同的哈希值。
  4. 单向性:从哈希值无法反推原始输入

常见算法

  • md5:较旧的哈希算法,已不推荐用于安全用途,但仍被一些应用使用。
  • sha1:较为常见的哈希算法,已不推荐用于安全用途。
  • sha256:当前广泛使用的安全哈希算法。
  • sha512:更强大的哈希算法,产生更长的哈希值
名称输出长度说明
md5128位(16字节)较旧的哈希算法,已不推荐用于安全用途,但仍被一些应用使用。
sha1160 位(20 字节)较为常见的哈希算法,已不推荐用于安全用途。
sha256256 位(32 字节)
sha512512 位(64 字节)
sha224224 位(28 字节)
sha384384 位(48 字节)
sha3-256256 位(32 字节)较新的安全哈希算法
sha3-512512 位(64 字节)较新的安全哈希算法
sha3-224224 位(28 字节)较新的安全哈希算法
sha3-384384 位(48 字节)较新的安全哈希算法

举例

基本使用

const crypto = require("crypto");
console.log("当前支持的hash算法列表", crypto.getHashes(), crypto.getHashes().join()); // RSA-MD5,RSA-RIPEMD160,RSA-SHA1,RSA-SHA1-2,RSA-SHA224,RSA-SHA256,RSA-SHA3-224,RSA-SHA3-256,RSA-SHA3-384,RSA-SHA3-512,RSA-SHA384,RSA-SHA512,RSA-SHA512/224,RSA-SHA512/256,RSA-SM3,blake2b512,blake2s256,id-rsassa-pkcs1-v1_5-with-sha3-224,id-rsassa-pkcs1-v1_5-with-sha3-256,id-rsassa-pkcs1-v1_5-with-sha3-384,id-rsassa-pkcs1-v1_5-with-sha3-512,md5,md5-sha1,md5WithRSAEncryption,ripemd,ripemd160,ripemd160WithRSA,rmd160,sha1,sha1WithRSAEncryption,sha224,sha224WithRSAEncryption,sha256,sha256WithRSAEncryption,sha3-224,sha3-256,sha3-384,sha3-512,sha384,sha384WithRSAEncryption,sha512,sha512-224,sha512-224WithRSAEncryption,sha512-256,sha512-256WithRSAEncryption,sha512WithRSAEncryption,shake128,shake256,sm3,sm3WithRSAEncryption,ssl3-md5,ssl3-sha1

// md5 的使用
// 1、创建一个 md5 哈希对象
const hash = crypto.createHash("md5");
// 2、要加密的数据
hash.update("hello");
// 3、获取最终的哈希值(以十六进制格式输出)
// 每个十六进制字符表示 4 位二进制数据。128位转化为十六进制就是 128/4 = 32 个十六进制字符。
const hashValue = hash.digest("hex");
console.log('md5(128 位,16个字节)',hashValue, hashValue.length);

console.log(
  "sha256(256 位,32个字节)",
  crypto.createHash("sha256").update("hello").digest("hex"),
  crypto.createHash("sha256").update("hello").digest("hex").length
);

但是在实际开发中,不会直接这样使用,而是 加盐(通过向原始数据(如密码)添加一个随机值(称为盐)来增加哈希的复杂度,防止一些常见的攻击方法,如彩虹表攻击和字典攻击。)

const crypto = require("crypto");
const hash = crypto.createHash("md5");

let salt = crypto.randomBytes(16).toString("hex");

hash.update("hello" + salt);
// 3、获取最终的哈希值(以十六进制格式输出)
// 每个十六进制字符表示 4 位二进制数据。128位转化为十六进制就是 128/4 = 32 个十六进制字符。
const hashValue = hash.digest("hex");
console.log("加盐值:", salt); // 加盐值: 9c82520f02a63d5bad96ce364d5728c8
console.log("加盐加密后", hashValue, hashValue.length); // 加盐加密后 88758b255e6748fa5238ddd5b6b1959f 32

// 使用固定的盐,
const hash1 = crypto.createHash("md5");
let salt1 = Buffer.from("123", "utf-8").toString("hex");
hash1.update("hello" + salt1);
const hashValue1 = hash1.digest("hex");
console.log("加盐值:", salt1); // 加盐值: 313233
console.log("加盐加密后", hashValue1, hashValue1.length); // 加盐加密后 3fb4b5daa2aeefc00a160c265d87128a 32

2、对称加密

对称加密是一种简单而快速的加密方式,它使用相同的密钥(称为对称密钥)来进行加密和解密。发送者和接收者在加密和解密过程中都使用相同的密钥。

在这里插入图片描述

特点

  1. 相同的密钥:发送方和接收方都需要拥有相同的密钥才能进行加密和解密操作。这意味着双方在通信之前需要安全地交换密钥。
  2. 速度较快
  3. 适合加密大量数据

常见算法

名称说明密钥长度
AESAES 是一种非常安全且高效的加密标准,被广泛应用于政府、金融、商业等多个领域。支持 128 位、192 位和 256 位密钥长度
DESDES 是一种历史较久的加密算法,曾经是美国的加密标准,但由于其 56 位密钥长度较短,已经不再安全,逐渐被替代。56位

举例

const crypto = require("crypto");

// 获取所有支持的加密算法
const ciphers = crypto.getCiphers();
console.log("Supported ciphers:", ciphers, ciphers.join()); // aes-128-cbc,aes-128-cbc-hmac-sha1,aes-128-cbc-hmac-sha256,aes-128-ccm,aes-128-cfb,aes-128-cfb1,aes-128-cfb8,aes-128-ctr,aes-128-ecb,aes-128-gcm,aes-128-ocb,aes-128-ofb,aes-128-xts,aes-192-cbc,aes-192-ccm,aes-192-cfb,aes-192-cfb1,aes-192-cfb8,aes-192-ctr,aes-192-ecb,aes-192-gcm,aes-192-ocb,aes-192-ofb,aes-256-cbc,aes-256-cbc-hmac-sha1,aes-256-cbc-hmac-sha256,aes-256-ccm,aes-256-cfb,aes-256-cfb1,aes-256-cfb8,aes-256-ctr,aes-256-ecb,aes-256-gcm,aes-256-ocb,aes-256-ofb,aes-256-xts,aes128,aes128-wrap,aes192,aes192-wrap,aes256,aes256-wrap,aria-128-cbc,aria-128-ccm,aria-128-cfb,aria-128-cfb1,aria-128-cfb8,aria-128-ctr,aria-128-ecb,aria-128-gcm,aria-128-ofb,aria-192-cbc,aria-192-ccm,aria-192-cfb,aria-192-cfb1,aria-192-cfb8,aria-192-ctr,aria-192-ecb,aria-192-gcm,aria-192-ofb,aria-256-cbc,aria-256-ccm,aria-256-cfb,aria-256-cfb1,aria-256-cfb8,aria-256-ctr,aria-256-ecb,aria-256-gcm,aria-256-ofb,aria128,aria192,aria256,camellia-128-cbc,camellia-128-cfb,camellia-128-cfb1,camellia-128-cfb8,camellia-128-ctr,camellia-128-ecb,camellia-128-ofb,camellia-192-cbc,camellia-192-cfb,camellia-192-cfb1,camellia-192-cfb8,camellia-192-ctr,camellia-192-ecb,camellia-192-ofb,camellia-256-cbc,camellia-256-cfb,camellia-256-cfb1,camellia-256-cfb8,camellia-256-ctr,camellia-256-ecb,camellia-256-ofb,camellia128,camellia192,camellia256,chacha20,chacha20-poly1305,des-ede,des-ede-cbc,des-ede-cfb,des-ede-ecb,des-ede-ofb,des-ede3,des-ede3-cbc,des-ede3-cfb,des-ede3-cfb1,des-ede3-cfb8,des-ede3-ecb,des-ede3-ofb,des3,des3-wrap,id-aes128-CCM,id-aes128-GCM,id-aes128-wrap,id-aes128-wrap-pad,id-aes192-CCM,id-aes192-GCM,id-aes192-wrap,id-aes192-wrap-pad,id-aes256-CCM,id-aes256-GCM,id-aes256-wrap,id-aes256-wrap-pad,id-smime-alg-CMS3DESwrap,sm4,sm4-cbc,sm4-cfb,sm4-ctr,sm4-ecb,sm4-ofb

// 密钥 (key):这是加密和解密操作所用的秘密密钥,必须保密。通常应该是随机生成并安全存储。
// 初始化向量 (iv):用于增加加密的随机性。aes-256-cbc 算法需要 16 字节的 IV(128 位)。

// 加密数据

// 1、设置密钥和初始化向量(IV)
const key = crypto.randomBytes(32); // 256位密钥
const iv = crypto.randomBytes(16); // 128位初始化向量

console.log("key", key, "长度", key.length);
console.log("iv", iv, "长度", iv.length);

// 2、创建加密器
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
const data = "我是呆呆狗";
// update() 方法用于加密数据,final() 方法用于结束加密过程并返回剩余部分。
// update() 方法的参数是待加密的数据,第二个参数是输入数据的编码,第三个参数是输出数据的编码。
let encryptedData = cipher.update(data, "utf8", "hex");

// final 方法的参数是输出数据的编码。
encryptedData += cipher.final("hex");

console.log("加密后的数据:", encryptedData);
console.log("Key:", key.toString("hex"));
console.log("IV:", iv.toString("hex"));

// 解密
// 1、创建解密器
const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);

// 2、解密数据
let decryptedData = decipher.update(encryptedData, "hex", "utf8");
decryptedData += decipher.final("utf8");

console.log("解密数据:", decryptedData);

在这里插入图片描述

比如在实际开发中,有些网站会对请求体的信息进行加密,这个时候就适合用 对称加密

3、非对称加密

在这里插入图片描述

非对称加密使用一对密钥,分别是公钥和私钥。发送者使用接收者的公钥进行加密,而接收者使用自己的私钥进行解密。公钥可以自由分享给任何人,而私钥必须保密。

常见的情况就是, 使用非对称加密来交换 对称加密的密钥,然后使用对称加密算法,来加密解密实际数据

特点

  1. 使用一对密钥,(公钥和私钥)
  2. 公钥加密,私钥解密。
  3. 加密效率较低

常见算法
RSA 这个是最长远的非对称加密算法之一

在这里插入图片描述

const crypto = require("node:crypto");
// 生成 RSA 密钥对
const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", {
  modulusLength: 2048,
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: { type: "pkcs8", format: "pem" },
});

console.log("私钥", privateKey);
console.log("公钥", publicKey);

// 要加密的数据
const text = "我是呆呆狗";

// 使用公钥进行加密
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(text, "utf-8"));
console.log("加密后的数据", encrypted.toString("hex"));

// 使用私钥进行解密
const decrypted = crypto.privateDecrypt(privateKey, encrypted);

console.log("解密后的数据", decrypted.toString("utf-8"));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值