crypto
crypto是Nodejs的一个密码学模块,能提供通用的加密和哈希算法
用纯JavaScript代码实现这些功能不是不可能,但速度会非常慢
而Nodejs用C/C++实现这些算法后,通过crypto这个模块暴露为JavaScript接口,这样方便快捷
密码学
密码学是计算机科学中的一个重要领域,它涉及到加密、解密、哈希函数和数字签名等技术
Nodejs提供了强大的密码学模块,使开发人员能够轻松地在其应用程序中实现各种密码学功能
对称加密
对称加密简单快速,使用相同的密钥(对称密钥)进行加密和解密,即发送者和接收者在加密和解密过程中都使用相同的密钥,适合对大量数据进行加密和解密操作
然而,对称密钥的安全性难以保证,因为需要确保发送者和接收者都安全地共享密钥,否则有被未授权的人获取密钥并解密数据的风险
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| const crypto = require('node:crypto')
const key = crypto.randomBytes(32)
const iv = Buffer.from(crypto.randomBytes(16))
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv)
cipher.update('野兽先辈', 'utf8', 'hex')
const secret = cipher.final('hex')
console.log(secret)
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv)
decipher.update(secret, 'hex', 'utf8')
console.log(decipher.final('utf8'))
|
非对称加密
非对称加密使用一对密钥,分别是公钥和私钥:发送者使用接收者的公钥进行加密,接收者使用自己的私钥进行解密
公钥可以自由分享给任何人,而私钥必须保密,所以非对称加密算法提供了更高的安全性,因为即使公钥泄露,只有持有私钥的接收者才能解密数据
然而非对称加密算法的加密速度相对较慢,不适合加密大量数据,因此,实际通常使用非对称加密交换对称密钥,然后使用对称加密算法加密实际的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const crypto = require('node:crypto')
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048, })
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from('野兽先辈', 'utf8'))
const secret = encrypted.toString('hex')
console.log(secret)
const decrypted = crypto.privateDecrypt(privateKey, encrypted)
console.log(decrypted.toString('utf8'))
|
哈希函数
哈希函数是单向的,意味着几乎不可能从哈希值推导出原始输入数据,即使输入数据发生微小的变化,其哈希值也会完全不同
哈希函数具有较低的碰撞概率,即不同的输入数据生成相同的哈希值的可能性应该非常小,几乎确保哈希值能够唯一地标识输入数据
无论输入数据的大小,哈希函数的输出长度是固定的,常见的哈希函数如MD5和SHA-256生成的哈希值长度分别为128位和256位
在避免密码明文传输,或验证文件完整性时,可以使用哈希函数:读取内容生成哈希,如果前端上传的哈希和后端读取的哈希匹配,说明验证成功
但哈希不见得非常安全,因为它们具有唯一性,有几率撞库碰到真实内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const crypto = require('node:crypto')
const hash = crypto.createHash('sha256')
hash.update('野兽先辈')
const secret = hash.digest('hex')
console.log(secret)
const secret2 = crypto.createHash('md5').update('野兽先辈').digest('hex')
console.log(secret2)
|