美文网首页
Node.js 上的 SHA256WithRSA 其实好简单

Node.js 上的 SHA256WithRSA 其实好简单

作者: Kenny锅 | 来源:发表于2019-06-24 23:16 被阅读0次

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

「用 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-----
`

注意:

  • 1、如果你公司的后端合适的是 Java 语言,就使用「PKCS8」密钥格式,也叫 「PKCS#8」,如果非 Java 语言可以考虑「PKCS1」。
  • 2、Java 使用private key 和 public key时,要把首尾「-----BEGIN PRIVATE KEY-----」之类的删除,但在 JavaScript 里使用时,一定要加上,后面会细讲原因。

二、前端(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)

  • param 是一个对象,格式为:{ alg: 'SHA256withRSA' } 或 { alg: 'SHA256withRSA', prov: 'cryptojs/jsrsa' }
  • alg 参数支持如下算法:
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) 作用

  • init(key, pass) - 用密钥来初始化此对象,用于后面的加密或验签工作。只需指定密钥,该方法就会调用 KEYUTIL 类初始化它。
    • key - 可以传下述类型参数:

      • PEM 格式的 PKCS#8 加密 RSA/ECDSA private key 必须包含 "BEGIN ENCRYPTED PRIVATE KEY"
      • PEM 格式的 PKCS#5 加密 RSA/DSA private key 必须包含 "BEGIN RSA/DSA PRIVATE KEY" 和 ",ENCRYPTED"
      • PEM 格式的 PKCS#8 字符串 RSA/ECDSA private key 必须包含 "BEGIN PRIVATE KEY"(注:例子中我采用的是这种,因为 jsrsasign 要求必传
      • PEM 格式的 PKCS#5 字符串 RSA/DSA private key 必须包含 "BEGIN RSA/DSA PRIVATE KEY" 但没有 ",ENCRYPTED"
      • RSAKey 对象 private key
      • KJUR.crypto.ECDSA 对象 private key
      • KJUR.crypto.DSA 对象 private key
    • pass - 传入生成 private key 和 public key 时的密码,可选参数

2.6 signature.updateString(inputString) 作用

  • signature.updateString(inputString) - 用于更新原字符串为签名或验证的字符串,这里还没有生成密文。

2.7 signature.sign() 作用

  • signature.sign() - 以十六进制字符串形式返回数据更新的签名,到就可以跟后端同事联调了。

2.8 hextob64(originSign) 作用

  • hextob64(originSign) - 将十六进制字符串签名转换为 Base 64,这样是为了方便传输(十六进制的签名有4k,但 Base 64 签名只有 2k )

参考:

全文完,谢谢阅读!

相关文章

  • Node.js 上的 SHA256WithRSA 其实好简单

    只要项目大一点或者跟金融沾点边,都要考虑数据传输的安全性。 「用 POST 请求」。对,这是入门级的安全措施。还有...

  • 《幸福其实好简单》

    秋天的落叶 碧蓝的天 还有 你看我时的眼神 2020.10.1...

  • 画画其实好简单

    比如……点点点就可以啦。

  • nodejs安装

    Node.js安装 目录 Node.js简单介绍 windows安装Node.js Linux安装Node.js ...

  • node.js制作简单的登录注册接口

    使用node.js制作的简单的登录注册的接口,首先,电脑上需要先安装好node.js,我使用的开发工具是vs...

  • Apk签名查看以及空白apk签名

    Apk签名查看 空白包签名 空白包签名SHA256withRSA问题处理

  • 好的收纳其实很简单

    平时工作忙的人,多数时候不会自己整理房间。但作为女人,对于收拾房子有天然的亲近感。所以会一直留意如何收纳。 对于没...

  • PHP RSA2 签名算法

    什么是RSA2? RSA2是在原来SHA1WithRSA签名算法的基础上,新增了支持SHA256WithRSA的签...

  • 其实生活简单即是好

    其实,快乐有很多种,丰富多彩的日常生活,已让大家忘记了最简单易懂的道理,平淡生活即是福气。然,当你静下心来,看...

  • PHP-RSA2签名

    什么是RSA2:RSA2就是在原来SHA1WithRSA签名算法的基础上,新增了支持SHA256WithRSA的签...

网友评论

      本文标题:Node.js 上的 SHA256WithRSA 其实好简单

      本文链接:https://www.haomeiwen.com/subject/scgaqctx.html