RSA加密算法是一种非对称加密算法。javascript
假设 A 与 B 通讯。A 和 B 都提供一个公开的公钥。A 把须要传递的信息,先用本身的私钥签名,再用 B 的公钥加密。B 接收到这串密文后,用本身的私钥解密,用 A 提供的公钥验签。html
为何要先签名后加密?若是你先加密后签名,非法用户经过获取的公钥就能够破解签名,破解以后就能够替换签名。java
详细的原理能够参考如下文档:
RSA算法原理(一)
RSA算法原理(二)node
在 node.js 中使用 rsa 算法,咱们使用的是 node-rsa 这个包。git
const NodeRSA = require('node-rsa'); const a_public_key_data = '-----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY-----'; const a_private_key_data = '-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----'; const b_public_key_data = '-----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY-----'; const b_private_key_data = '-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----'; // 生成 A 的公私钥对象 const a_public_key = new NodeRSA(a_public_key_data); const a_private_key = new NodeRSA(a_private_key_data); // 生成 B 的公私钥对象 const a_public_key = new NodeRSA(a_public_key_data); const a_private_key = new NodeRSA(a_private_key_data); const text = 'Hello RSA!'; // 加签并加密 const sign = a_private_key.sign(text, 'base64', 'utf8'); console.log('A 私钥加签:', sign); const encrypted = a_public_key.encrypt(sign, 'base64'); console.log('B 公钥加密:', encrypted); // 解密并验签 const decrypted = a_public_key.decrypt(encrypted, 'utf8'); console.log('B 私钥解密:', decrypted); const verify = a_public_key.verify(text, decrypted, 'utf8', 'base64'); console.log('A 公钥验签:', verify);
接口传递的通常是复杂的对象,因此咱们须要把对象按必定的顺序排列并序列化成字符串再进行签名加密的操做github
const serialize = (obj) => { const str = []; Object.keys(obj).sort().forEach((key) => { if (obj.hasOwnProperty(key)) { str.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])); } }); return str.join('&'); };
RSA 算法有必定的计算量,加上 Node 不适合作计算密集型的操做。当接口被频繁调用可能会占用主线程,阻塞其余接口,使用了 RSA 的接口并发量会降低十倍左右。如非必要,谨慎在 Node 里使用 RSA。算法