zoukankan      html  css  js  c++  java
  • node-rsa非对称加密

    写在最前:此文的目的是介绍编码,减少刚接触时的弯路,所以内容且不做详细累述

    一.使用 node-rsa 进行非对称加解密

    • 因为 比特币 中使用的非对称加密,所以在npm中对比找到一个比较方便也直观的库:node-rsa

    • 非对称加密的关键在于 有 公钥 / 私钥
      用法:
      a.生成一对公钥私钥
      b.公钥加密 -> 对应私钥解密
      c.私钥加密 -> 对应公钥解密

    • 非对称加密的常见应用方式
      a.公钥加密,发给私钥拥有者,私钥解密获得明文。其它人用公钥解不开
      b.私钥加密(签名)

    • 公钥的传输(混合加密)
      a.使用对称加密算法发布公钥
      b.使用对称加密算法解密公钥,再使用公钥加密明文,发给私钥拥有者

    注:不能 公钥加密公钥解密 或 私钥加密私钥解密

    二.几个重要概念

    秘钥内容格式与传输格式
    1. DER 和 PEM 编码

    • DER: 基于二进制的编码。可以用CER或者CRT作为扩展名的的整数。比较合适的说法是“我有一个DER编码的证书”,而不是“我有一个DER证书”。【编码规则参考】

    • PEM: 基于ASCII(Base64)的编码。OpenSSL 使用 PEM 文件格式存储证书和密钥。【编码规则参考】
      PEM 实质上是 base64 编码的二进制内容,再进行增加或裁剪特殊字符-、 、 、begin信息、end信息等,如:

    -----BEGIN CERTIFICATE-----
    内容
    -----END CERTIFICATE-----
    

    注:本文中的私钥公钥都是用 pem 格式

    2. PKCS(The Public-Key Cryptography Standards)

    • 由美国RSA公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。
    • 版本:现有PCKS1,PCKS3,PCKS5,PKCS6,PKCS7,PKCS8,PKCS9,PKCS10,PKCS11,PKCS12,PKCS13,PKCS14,PKCS15 共 13个版本
      常用:PCKS1 和 PCKS8,本文使用 PCKS8 标准

    注:由于PKCS内容规范设计二进制,不方便使用,所以一般转成 base64 后,用 pem 格式规范显示

    • PCKS1 的pem格式头:
    //公钥
    -----BEGIN RSA PUBLIC KEY-----
    MEgCQQCpb53RwojJX+lxHiEMfNmixx+eIV+u+d9e61Ecx8MVBW0tzAoxTpdTKrgN
    9hdBqaP6rtQMxOp/4++C5+3zh6D1AgMBAAE=
    -----END RSA PUBLIC KEY-----
    //私钥
    -----BEGIN RSA PRIVATE KEY-----
    MIIBPAIBAAJBAKlvndHCiMlf6XEeIQx82aLHH54hX675317rURzHwxUFbS3MCjFO
    l1MquA32F0Gpo/qu1AzE6n/j74Ln7fOHoPUCAwEAAQJAJO8tyeHMC4may4uzzJMS
    pgcd/0xrHSte48QMBGgPQG95imYXELKQUV2rjzsua9xJP5huQjhe+qrmBpEqrtf7
    wQIhANccK0zuFaH4CoIuKsp92YB6OGwndy6UJaiX2RoUw0V5AiEAyaTTkar73r4d
    OB2s4Ofj+UkGX/aspp0dM+7V5HathF0CIQCezlYNSmvAEr23U9wVeAmd9x02g4BS
    a97Nc6U8wv1SiQIhAKap7ZTA1l1MlaoEHRfnkq5AhVxb7mfoBHMgPPoQfWqhAiEA
    npkku9LfP2mlCCB85/zxsUehZOwoMVLlF2dSLWsrURs=
    -----END RSA PRIVATE KEY-----
    
    • PCKS8 的pem格式头:注意私钥头中没有 RSA
    //公钥
    -----BEGIN PUBLIC KEY-----
    MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKzY3F21g7UWaTcIk/ltUy4LuuHK5Hhl
    9ZpdxDr4+WA7pNwhCzhgBKbWUa+XotUYet841I2mYPJ6+6X32LwotF0CAwEAAQ==
    -----END PUBLIC KEY-----
    //私钥
    -----BEGIN PRIVATE KEY-----
    MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEArNjcXbWDtRZpNwiT
    +W1TLgu64crkeGX1ml3EOvj5YDuk3CELOGAEptZRr5ei1Rh63zjUjaZg8nr7pffY
    vCi0XQIDAQABAkBUJ3GDHnD1peesJ70D37pz3LosXMBH7jxZ3/U+USH5O8M7ixzt
    lpYa+ITcuL0MKxvVyVYw5Pvaui1+Nq9LV17xAiEA5VMCIgtn3WFEOpP+sVhHlqPc
    VbTfE3g0RlDfUt/sQ5sCIQDA9AiJ65G3pHJJxYNc9RB/lVav3anFkbgnGKolPw8T
    ZwIhAIs7QLpGzoLcgT5HiIVIIf7V8fqfXClH/AUNKOn6RkotAiEAo6HQY/ZMeyqQ
    aZOA1aJWPXxOKZKX2R68xxsZn8Ccbl0CIQDck74y8SzLRSBB6JgVZ6NoWkWI5tyj
    V8RFCZU9VUinQA==
    -----END PRIVATE KEY-----
    

    三.代码示例

    /** from: @jameszou707
     * 1.使用 node-rsa 生成 公钥和私钥,并进行服务端测试
     * @param pkcsType :pkcs版本(pkcs1/pkcs8),默认为 pkcs8
     */
    function generateKeyPair() {
      pkcsType = pkcsType ? pkcsType : 'pkcs8';//不为空则 设置为传入参数,为空则 设置为 pkcs8
      console.log('pkcsType=' + pkcsType);
    
      //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);
      
      //---------------------测试1:服务端私钥加密公钥解密------------------------
      //3.使用 私钥 加密 数据,并指定 字符编码 和 字符集
      var encryData = key.encryptPrivate('服务端测试 -> jameszou love code~~~', 'base64','utf8');
      console.log('
    私钥加密后的数据:
    ', encryData); //加密后数据为 base64 编码
    
      //4.使用 公钥 解密 数据,并指定字符集
      var decryptData = key.decryptPublic(encryData,'utf8');
      console.log('
    公钥解密后的数据:
    ', decryptData);
    
      //---------------------测试2:服务端加载公钥后解密------------------------
      //1.创建RSA对象,并指定 秘钥长度
      var key2 = new NodeRSA({ b: pkcsSize });
      //2.导入 公钥,并指定使用 pkcs标准,pem格式
      key2.importKey(publicPem, pkcsType+'-public-pem');
    
      //3.使用 公钥 解密数据
      var decrypted = key2.decryptPublic(encryData, 'utf8');  
      console.log('
    使用公钥解密后的数据:
    ',decrypted);
    }
    

    四.可能遇到的错误

    • 暂无
  • 相关阅读:
    js下载doxc 文件示例和部分后缀对应的content-type 总结
    使用react-app-rewired和customize-cra对默认webpack自定义配置
    koa2使用es7 的装饰器decorator
    vue history 模式打包部署在域名的二级目录的配置指南
    linux 安装 node 环境
    javascript 正则表达式之分组与前瞻匹配详解
    vue的$emit 与$on父子组件与兄弟组件的之间通信
    mysql 的基本操作总结--增删改查
    mysql 常用的时间日期函数小结
    小程序封装request请求,统一API
  • 原文地址:https://www.cnblogs.com/jameszou/p/9238939.html
Copyright © 2011-2022 走看看