Node.js 上的 SHA256WithRSA 其实好简单

2019-06-24  本文已影响0人  Kenny锅

只要项目大一点或者跟金融沾点边,都要考虑数据传输的安全性。

「用 POST 请求」。对,这是入门级的安全措施。还有没有高级一点的?(想要 GET 请求安全也不是不可能)

「那就用 HTTPS传输」。很对,这是一个非常重要的方案,这已经是中级的安全方案。

有没有中高级的安全方案?有,就是数据签名与验签。如果对接过支付宝支付、微信支付的朋友都很熟悉,如果没有对接过,我就跟大家聊聊。

我知道大家都很忙,没有时间听我啰嗦,我先把核心代码放出来,你先把功能实现了,回过头来细细听我唠叨。

一、private key 和 public key

大家可以通过如下这个网站生成 private key 和 public key(或者直接用我粘出来的两个 key 也行):http://web.chacuo.net/netrsakeypair

const privateKeyString = `
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIYSs8zydPxowvlnX+9vyDRS52nNwQocDcmpXyVfMY5F+1UdmVcktwbWAzjpAZHlmNjtSYYxMkp1jedDCFBVvcQGu1ulbT7yvGY8FFRfMG0UbXT7m3hUK6IHCVYUWKCGI2+HI44V26O+pq/KvIY96Oy+X1zZa1cv2aEb3GFnH+D1AgMBAAECgYAq8li4AL5qkCBMhcmcSCFIaXoJUUhRtbTQ8TkyHnEgUth0ZlvVJ0SdovY7R6AiHPq+GhxgKOgkI83F05oZKa30YUXY5MVhUYbBvjeifbTG3lIeDwL1s51nRIUBcGEyfnDfotePtt4quxV5cXNUcsNVymgA7Pin/6bGsc062ZsQgQJBAN6VGh39fDVzqHqhPpf4WsgOvmSC5RzPMobNEP0lU9SNat86Othg6tz3h3u3vRNsXMu+n+9F5oRFbJobiXhlt6ECQQCaM8P3bYpKwImAm0gmUixIoF0wwlnYm7PHcr5P1hYHrMvxS7dT5PdHKihJAnIYhtLG6bfdzFv/Kb4XP0Gf5xjVAkBLOk2XcUL3td1thO3o4xGbqBAFXJAfCpBjKw/g3yrUHe/O/plA5JC8mhR6ZgFLfUZnvkfD0PY2IliwRTpTLN3BAkBSxAYjAACCLuWeybnoF6L9OFXMngRrZucP3l6Xq2kXpX+xe9pihTrUT6Rfy5hB4duwODIgMlgOlPEauTEYCoohAkEAgmSF5pYELbvOW9eO9tQrFm20qf/9sXHi1Z87qSzGxA3HqcrqPe73L3nfxg5nrgOwg0ZqNl1wNBXti+LxXa7DeQ==
-----END PRIVATE KEY-----
`
const publicKeyString = `
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGErPM8nT8aML5Z1/vb8g0UudpzcEKHA3JqV8lXzGORftVHZlXJLcG1gM46QGR5ZjY7UmGMTJKdY3nQwhQVb3EBrtbpW0+8rxmPBRUXzBtFG10+5t4VCuiBwlWFFighiNvhyOOFdujvqavyryGPejsvl9c2WtXL9mhG9xhZx/g9QIDAQAB
-----END PUBLIC KEY-----
`

注意:

二、前端(APP端)加密

一般都是大前端使用 private key 生成加密数据 ,传给后端接口,后端使用 public key 验证加密信息,所以我只需要准备编写如下代码即可:

import { KEYUTIL, KJUR, hextob64, hextob64u } from 'jsrsasign';

const privateKeyString = `
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIYSs8zydPxowvlnX+9vyDRS52nNwQocDcmpXyVfMY5F+1UdmVcktwbWAzjpAZHlmNjtSYYxMkp1jedDCFBVvcQGu1ulbT7yvGY8FFRfMG0UbXT7m3hUK6IHCVYUWKCGI2+HI44V26O+pq/KvIY96Oy+X1zZa1cv2aEb3GFnH+D1AgMBAAECgYAq8li4AL5qkCBMhcmcSCFIaXoJUUhRtbTQ8TkyHnEgUth0ZlvVJ0SdovY7R6AiHPq+GhxgKOgkI83F05oZKa30YUXY5MVhUYbBvjeifbTG3lIeDwL1s51nRIUBcGEyfnDfotePtt4quxV5cXNUcsNVymgA7Pin/6bGsc062ZsQgQJBAN6VGh39fDVzqHqhPpf4WsgOvmSC5RzPMobNEP0lU9SNat86Othg6tz3h3u3vRNsXMu+n+9F5oRFbJobiXhlt6ECQQCaM8P3bYpKwImAm0gmUixIoF0wwlnYm7PHcr5P1hYHrMvxS7dT5PdHKihJAnIYhtLG6bfdzFv/Kb4XP0Gf5xjVAkBLOk2XcUL3td1thO3o4xGbqBAFXJAfCpBjKw/g3yrUHe/O/plA5JC8mhR6ZgFLfUZnvkfD0PY2IliwRTpTLN3BAkBSxAYjAACCLuWeybnoF6L9OFXMngRrZucP3l6Xq2kXpX+xe9pihTrUT6Rfy5hB4duwODIgMlgOlPEauTEYCoohAkEAgmSF5pYELbvOW9eO9tQrFm20qf/9sXHi1Z87qSzGxA3HqcrqPe73L3nfxg5nrgOwg0ZqNl1wNBXti+LxXa7DeQ==
-----END PRIVATE KEY-----
`

export function sha256withRSA(inputString) {
    const key = KEYUTIL.getKey(privateKeyString);
    // 创建 Signature 对象,设置签名编码算法
    const signature = new KJUR.crypto.Signature({ alg: 'SHA256withRSA' });
    // 初始化
    signature.init(key);
    // 传入待加密字符串
    signature.updateString(inputString);
    // 生成密文
    const originSign = signature.sign();
    // const sign64 = hextob64(originSign);
    // console.log('sign base64 =======', sign64);
    // const sign64u = hextob64u(originSign);
    // console.log('sign base64u=======', sign64u);
    return originSign;
}

把 public key 给后端同事,注意:不要带首尾 ----- 两行。

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGErPM8nT8aML5Z1/vb8g0UudpzcEKHA3JqV8lXzGORftVHZlXJLcG1gM46QGR5ZjY7UmGMTJKdY3nQwhQVb3EBrtbpW0+8rxmPBRUXzBtFG10+5t4VCuiBwlWFFighiNvhyOOFdujvqavyryGPejsvl9c2WtXL9mhG9xhZx/g9QIDAQAB

到这儿,差不多就可以了收工了。

------------------------------- 好奇少年分割线 -------------------------------

三、jsrsasign API 简介

3.1 谁加密,谁验证?

发起方 动作 key
大前端 加密 用 private key
大前端 验证加密 用 public key
后端 加密 用 private key
后端 验证加密 用 public key

3.2 KEYUTIL, KJUR, hextob64, hextob64u 分别都是什么

3.3 KEYUTIL.getKey 作用

API:KEYUTIL.getKey(param, passcode, hextype)
param:通过入参获取 private key 或 public key 对象
passcode:传入 private key 或 public key 生成时的密码(可选参数)
hextype: 传入pkcs8prvpkcs5prvpkcs8pubx509pub 之类的值(可选参数)
更多详情:https://kjur.github.io/jsrsasign/api/symbols/KEYUTIL.html#.getKey

3.4 KJUR.crypto.Signature 作用

KJUR.crypto.Signature 非常简单的「模拟」了 java.security.Signature 类,跟 Java 一样,在 new 时给 constructor 传参
API:KJUR.crypto.Signature(param)

MD5withRSA - cryptojs/jsrsa
SHA1withRSA - cryptojs/jsrsa
SHA224withRSA - cryptojs/jsrsa
SHA256withRSA - cryptojs/jsrsa
SHA384withRSA - cryptojs/jsrsa
SHA512withRSA - cryptojs/jsrsa
RIPEMD160withRSA - cryptojs/jsrsa
MD5withECDSA - cryptojs/jsrsa
SHA1withECDSA - cryptojs/jsrsa
SHA224withECDSA - cryptojs/jsrsa
SHA256withECDSA - cryptojs/jsrsa
SHA384withECDSA - cryptojs/jsrsa
SHA512withECDSA - cryptojs/jsrsa
RIPEMD160withECDSA - cryptojs/jsrsa
MD5withRSAandMGF1 - cryptojs/jsrsa
SHA1withRSAandMGF1 - cryptojs/jsrsa
SHA224withRSAandMGF1 - cryptojs/jsrsa
SHA256withRSAandMGF1 - cryptojs/jsrsa
SHA384withRSAandMGF1 - cryptojs/jsrsa
SHA512withRSAandMGF1 - cryptojs/jsrsa
RIPEMD160withRSAandMGF1 - cryptojs/jsrsa
SHA1withDSA - cryptojs/jsrsa
SHA224withDSA - cryptojs/jsrsa
SHA256withDSA - cryptojs/jsrsa

2.5 signature.init(key) 作用

2.6 signature.updateString(inputString) 作用

2.7 signature.sign() 作用

2.8 hextob64(originSign) 作用

参考:

全文完,谢谢阅读!

上一篇 下一篇

猜你喜欢

热点阅读