在线生成秘钥
- 非对称加密公钥私钥对
 - 在线生成公私钥对
 - RSA Key pair create
 - 生成RSA密钥对
 
http://web.chacuo.net/netrsakeypair
RSA参考资料 https://blog.csdn.net/aihouti2211/article/details/101167013
const NodeRSA = require('node-rsa')const BASE64 = 'base64'const UTF8 = 'utf8'const pkcsSize = 512const str = '服务端测试 -> miaomiaomiao~~~'demo()function demo() {pkcsType = 'pkcs8'//不为空则 设置为传入参数,为空则 设置为 pkcs8// 1.创建RSA对象,并指定 秘钥长度var key = new NodeRSA({ b: pkcsSize })key.setOptions({ encryptionScheme: 'pkcs1' })//指定加密格式// 2.生成 公钥私钥,使用 pkcs8标准,pem格式var publicPem = key.exportKey(pkcsType+'-public-pem')//制定输出格式var privatePem = key.exportKey(pkcsType + '-private-pem')// console.log(key.$options)console.log(pkcsType+'公钥:',publicPem)console.log(pkcsType+'私钥:', privatePem)//---------------------demo1:服务端私钥加密公钥解密----------------------// 3.使用 私钥 加密 数据,并指定 字符编码 和 字符集var encryData = key.encryptPrivate(str, BASE64, UTF8)console.log('私钥加密后的数据:', encryData) //加密后数据为 base64 编码// 4.使用 公钥 解密 数据,并指定字符集var decryptData = key.decryptPublic(encryData, UTF8)console.log('公钥解密后的数据:', decryptData)//---------------------demo2:服务端加载公钥后解密----------------------// 1.创建RSA对象,并指定 秘钥长度var publicKey = new NodeRSA({ b: pkcsSize })// 2.导入 公钥,并指定使用 pkcs标准,pem格式publicKey.importKey(publicPem, pkcsType+'-public-pem')// 3.使用 公钥 解密数据var decrypted = publicKey.decryptPublic(encryData, UTF8)console.log('使用公钥解密后的数据',decrypted)//---------------------demo3:服务端使用私钥签名----------------------// 1. 私钥var privateKey = new NodeRSA({ b: pkcsSize })// 2.导入 私钥,并指定使用 pkcs标准,pem格式privateKey.importKey(privatePem, pkcsType+'-private-pem')var signedData = privateKey.sign(Buffer.from(str), BASE64).toString(BASE64)console.log('\n使用私钥签名:', signedData)//---------------------demo4:服务端使用公钥验证签名----------------------var result = publicKey.verify(Buffer.from(str), signedData, 'Buffer', BASE64)console.log('验证签名结果', result)}
key的格式
- pkcs1格式:
- ——-BEGIN RSA PRIVATE KEY——-
 - ——-END RSA PRIVATE KEY———
 
 - ——-BEGIN RSA PRIVATE KEY——-
 - pkcs8格式:
- ——-BEGIN PRIVATE KEY——-
 - ——-END PRIVATE KEY——
 
 
pub.key
非对称加密公钥,用txt记事本,将下面加密字符串存为 pub.key
-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoesjh94ijH7jHcgyIEcj9JaJqrNGVNq/sOoYdBD9t21hUZdTdfGQ2jQi62rFXLDvmHlrWdSO1InNZ0UWeWtLIpD7F+aiKtjidVbATIh4ZONzOHyXUE/xO2L1mtssoNFP/wtyAAgBsw27Wun9jyHq5nyt2+7S7uqH6tvkD7LBdcwIDAQAB-----END PUBLIC KEY-----
pri.key
非对称加密私钥,用txt记事本,将下面加密字符串存为 pri.key
-----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKh6yOH3iKMfuMdyDIgRyP0lomqs0ZU2r+w6hh0EP23bWFRl1N18ZDaNCLrasVcsO+YeWtZ1I7Uic1nRRZ5a0sikPsX5qIq2OJ1VsBMiHhk43M4fJdQT/E7YvWa2yyg0U//C3IACAGzDbta6f2PIermfK3b7tLu6ofq2+QPssF1zAgMBAAECgYBYZeQUu94TSMeYzfxJQJumRyLKudZVZhYz6hkIDHyDVX0o+y0O8P9bp/AWqjw2Mt1SxkZ/E4MivOqtC6JtjdXd2k9qFnLiG1a7DqS75533pddTGdDEPqMwWKbE1KHJlSv6V/IrsY/n9PeyksPsrv+r+KTGFHVQMWCC0/MTCwlb0QJBANbziZiUJOYiQLZ5pnL5V/iPM5+2iUg2sqpcvRNkd3ydkgoiF46jWw4hbeGuoVf/HQwZWcJ7leJD2K50McXjwV8CQQDIp1sgrJT/NQ/D+h3qI0lJICNTjjfBot1qG2oEymQDYsBrhVQgya3GwXqTxJGjgersE4nGl2FiYDdK3lDkffhtAkEAkA3cy/2UkQqpleEHNQx38WN/NG0vqc7GhDfsmx98mG49Xj8kzHob3ud2bYYMKR4WyHIA3r7WXzIa+Cd05+tQPwJBAIzJF+BaFwTllxU7hgfFEGOVgBPdQnPDsTUE3SNVWk0h2b7XQsrqltpQ4I+TqVgfDNTtdIr5piOfPMx0Ji/bzxUCQATRPvrd0PObEhRTaeXmdPCFZhROtuyBkg85q/qZXwnKNvz1ivwi48DEDxGQXM2WINi2n78xMxrbsZhZtTycXVE=-----END PRIVATE KEY-----
pub.key报错
——-BEGIN RSA PRIVATE KEY——- ,替换为 ——-BEGIN PUBLIC KEY——-
node服务端加密
node-rsa
- github文档 https://github.com/rzcoder/node-rsa
 - node-rsa加解密、签名以及验签
 - RSA加密的好处
- 签名防止参数篡改
 - 加密防止参数敏感信息泄漏
 
 
加密解密流程
双方都维护一套公私钥, 发送方(a,b)-> 接收方 (c,d)
a. 自己的私钥签名
b. 对方的公钥加密
c. 私钥解密
d. 公钥验证签名,参数是否被篡改 && 调用方是否是期望的
rsa/index.js
const NodeRSA = require('node-rsa')const fs = require('fs')// 公钥加密export function encrypt(data) {const publicKey = fs.readFileSync('./files/rsa.pub.key')const nodersa = new NodeRSA(publicKey)// 要加上是个配置,否则后端解密失败,不写setOptions,加密的结果是错误的// 在node-rsa模块中加解密默认使用 pkcs1_oaep ,而在js中加密解密默认使用的是 pkcs1nodersa.setOptions({ encryptionScheme: 'pkcs1' })const encrypted = nodersa.encrypt(data, 'base64')return encrypted}// 私钥解密export function decrypt(data) {const privateKey = fs.readFileSync('./files/rsa.pri.key')const nodersa = new NodeRSA(privateKey)const decrypted = nodersa.decrypt(data, 'utf8')return decrypted}
使用
import { encrypt, decrypt} from './rsa/index.js'const data = { name: 'owen', age: 20 }// 加密const encrypted = encrypt(data)console.log('encrypted:', encrypted)// 解密const decrypted = decrypt(encrypted)console.log('decrypted:', decrypted)
pscs1
RSA是一种块加密的算法,所以对于明文需要将他们分成固定的块长度,考虑到输入的数据长度的问题:
所以加解密的填充有好几种:
无填充,就是直接对明文进行加密
PKCS1。将数据长度分成密钥长度-11byte,比如密钥是1024bit,那么长度就是1024/8-11=117bytes,具体的格式:先填0,2,然后随机生成其他的byte,后面才是真正的数据
PKCS1_OAEP将数据长度分成密钥长度-41byte,比如密钥是1024bit,那么长度就是1024/8-41=77bytes,先填0,随机或者是固定的测试向量加20个bytes,然后加20个数字签名的数据,最后才是数据
SSLV23,将数据长度分成密钥长度-11byte,比如密钥是1024bit,那么长度就是1024/8-11=117bytes,具体的格式:先填0,2,填入8个3,填入一个’\0’,最后才是真正的数据
react前端POST加密
const NodeRSA = require('node-rsa')// 公钥加密export function encrypt(data) {const publicKey = `-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoesjh94ijH7jHcgyIEcj9JaJqrNGVNq/sOoYdBD9t21hUZdTdfGQ2jQi62rFXLDvmHlrWdSO1InNZ0UWeWtLIpD7F+aiKtjidVbATIh4ZONzOHyXUE/xO2L1mtssoNFP/wtyAAgBsw27Wun9jyHq5nyt2+7S7uqH6tvkD7LBdcwIDAQAB-----END PUBLIC KEY-----`const nodersa = new NodeRSA(publicKey)const encrypted = nodersa.encrypt(data, 'base64')return encrypted}// 私钥解密export function decrypt(data) {const privateKey = `-----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKh6yOH3iKMfuMdyDIgRyP0lomqs0ZU2r+w6hh0EP23bWFRl1N18ZDaNCLrasVcsO+YeWtZ1I7Uic1nRRZ5a0sikPsX5qIq2OJ1VsBMiHhk43M4fJdQT/E7YvWa2yyg0U//C3IACAGzDbta6f2PIermfK3b7tLu6ofq2+QPssF1zAgMBAAECgYBYZeQUu94TSMeYzfxJQJumRyLKudZVZhYz6hkIDHyDVX0o+y0O8P9bp/AWqjw2Mt1SxkZ/E4MivOqtC6JtjdXd2k9qFnLiG1a7DqS75533pddTGdDEPqMwWKbE1KHJlSv6V/IrsY/n9PeyksPsrv+r+KTGFHVQMWCC0/MTCwlb0QJBANbziZiUJOYiQLZ5pnL5V/iPM5+2iUg2sqpcvRNkd3ydkgoiF46jWw4hbeGuoVf/HQwZWcJ7leJD2K50McXjwV8CQQDIp1sgrJT/NQ/D+h3qI0lJICNTjjfBot1qG2oEymQDYsBrhVQgya3GwXqTxJGjgersE4nGl2FiYDdK3lDkffhtAkEAkA3cy/2UkQqpleEHNQx38WN/NG0vqc7GhDfsmx98mG49Xj8kzHob3ud2bYYMKR4WyHIA3r7WXzIa+Cd05+tQPwJBAIzJF+BaFwTllxU7hgfFEGOVgBPdQnPDsTUE3SNVWk0h2b7XQsrqltpQ4I+TqVgfDNTtdIr5piOfPMx0Ji/bzxUCQATRPvrd0PObEhRTaeXmdPCFZhROtuyBkg85q/qZXwnKNvz1ivwi48DEDxGQXM2WINi2n78xMxrbsZhZtTycXVE=-----END PRIVATE KEY-----`const nodersa = new NodeRSA(privateKey)const decrypted = nodersa.decrypt(data, 'utf8')return decrypted}
node-rsa错误
react npm run build node-rsa 1.1.1 版本会报错,版本降级为 “node-rsa”: “1.0.5”
Failed to minify the code from this file./node_modules/node-rsa/src/formats/openssh.js
后端无法解密的错误
- 原因:因为加密标准:“RSA/ECB/PKCS1Padding” 与’RSA”不一样 ```jsx // Android中应该使用这个标准 Cipher cipher = Cipher.getInstance(“RSA/ECB/PKCS1Padding”)
 
// 服务端使用这个标准 Cipher cipher = Cipher.getInstance(“RSA”) ```
- 前端RSA加密后的Base64位的密文,在后端接收到时,字符”+”被转为了空格,导致无法解密成功
- 解决: 后端解密之前先做一次字符替换,将空格转回”+”,再进行解密
 
 
