<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      前端RSA密鑰生成和加解密——window.crypto使用相關

      轉自簡書,原文地址,本文介紹window.crypto關于RSA方面的API。


      crypto API支持常用的rsa、aes加解密,這邊介紹rsa的應用。

      瀏覽器兼容性

      window.crypto需要chrome 37版本,ie 11,safari 11才支持全部API而基本的加解密在safari 7就可以。

      生成公私鑰

      crypto.subtle.generateKey(algorithm, extractable, keyUsages),其中:
      1.algorithm參數根據不同算法填入對應的參數對,rsa需要填入RsaHashedKeyGenParams對象包含有:

      • name,可選RSASSA-PKCS1-v1_5, RSA-PSS, or RSA-OAEP,這邊如果用于加解密是不支持舊的RSAES-PKCS1-v1_5的(jsencrypt.js支持),RSASSA-PKCS1-v1_5用于簽名

      • modulusLength,為rsa位數,推薦至少2048位(相當于112位的aes)才能較為安全,此參數最為影響性能,比如1024比2048快非常多,NIST建議目前的RSA秘鑰安全強度是2048位,如果需要工作到2030年之后,就使用3072位的秘鑰

      • publicExponent,一般直接為[0x01, 0x00, 0x01]

      • hash,摘要方式,可選SHA-256SHA-384SHA-512,這邊也允許SHA-1,但是因為其安全性所以基本不建議

      2.extractable一般是true,表示是否允許以文本的方式導出key

      3.keyUsages是一個數組,里面可選encryptdecryptsign

      window.crypto.subtle.generateKey(
          {
              name: "RSA-OAEP",
              modulusLength: 2048,
              publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
              hash: {
                  name: "SHA-512" // 這邊如果后端使用公鑰加密,要注意與前端一致
              },
          },
          true,
          ["encrypt", "decrypt"] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
      )
      

      函數結果返回一個promise對象,如果是對稱加密會得到一個密鑰CryptoKey類型,這邊rsa會得到一個密鑰對CryptoKeyPair,它有2個CryptoKey成員,privateKeypublicKey,我們導出密鑰為文本或者加解密都將通過這2個成員對象。

      導出公私鑰

      window.crypto.subtle.exportKey(format, key),其中:
      1.format可選rawpkcs8spkijwk,我們這邊在導出公鑰時選spki,私鑰選pkcs8

      2.key就是上面CryptoKeyPairprivateKey或者publicKey
      函數返回一個promise對象,結果是一個ArrayBuffer,這邊轉成pem風格。

      // 導出私鑰
       window.crypto.subtle.exportKey(
          "pkcs8", // 公鑰的話這邊填spki
          key.privateKey // 公鑰這邊是publicKey
      ).then(function(keydata2) {
          let privateKey = RSA2text(keydata1, 1) // 私鑰pem
      }).catch(function(err) {
          console.error(err)
      })
      // pem格式文本
      function RSA2text(buffer, isPrivate = 0) {
          let binary = ''
          const bytes = new Uint8Array(buffer)
          const len = bytes.byteLength
          for (let i = 0; i < len; i++) {
              binary += String.fromCharCode(bytes[i])
          }
          const base64 = window.btoa(binary)
          let text = "-----BEGIN " + (isPrivate ? "PRIVATE" : "PUBLIC") + " KEY-----\n" // 這里-----BEGIN和-----是固定的
          text += base64.replace(/[^\x00-\xff]/g, "$&\x01").replace(/.{64}\x01?/g, "$&\n") // 中間base64編碼
          text += "\n-----END " + (isPrivate ? "PRIVATE" : "PUBLIC") + " KEY-----" // 這里-----END和-----是固定的
          return text
      }
      

      導入公私鑰

      window.crypto.subtle.importKey(
      format,
      keyData,
      algorithm,
      extractable,
      keyUsages
      )
      ,其中:
      1.format可選rawpkcs8spkijwk,對應之前生成時的選擇,我們這邊在導入公鑰時選spki,私鑰選pkcs8

      2.keyData,即window.crypto.subtle.exportKey獲得的ArrayBuffer,由于在這里時我們一般只有pem文本的,所以還需要做轉換成ArrayBuffer。

      3.algorithm這邊我們是rsa,需要填入一個RsaHashedImportParams對象,這邊對應crypto.subtle.generateKey所需的RsaHashedKeyGenParams對象,含有:

      • name,都保持與之前一致
      • hash

      4.extractablecrypto.subtle.generateKey

      5.keyUsagescrypto.subtle.generateKey
      函數返回一個promise對象,結果是一個CryptoKey

      // 導入公鑰
      const pub = "-----BEGIN PUBLIC KEY-----
      MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo5NwYVVSg6rmAIKoxvCI
      4Rn7FYh0mOFrnr0q2+r99/ZGuYCj5b6FQ8BwaaU8XpRn/y3W7W2bCggNRwllWQ2r
      dHIM+6vN2Yi/QYntKqbcRNlK1s02G2lw9pERaWi15+5P8+AFR8IHANm/Dd/19OlM
      5FZ9hh+qG7FXFhV2i4r62pUZxhk6ykItOT16IH5poK9eEDhqsXZ+3UW6cGlxANgO
      jHJEnZpNCI5tS/4kFhLogHvEd88MoapljL6cZXk3ZafvxgUwxI6BZIhlw0adh2sj
      bByIHitjRxqKMDH7uSdV9zf8t5Wa0bZFcUpcb5Jx2QBWIlO1qP+Q4LLMbNvEHeBC
      4wIDAQAB
      -----END PUBLIC KEY-----"
      
      const pemHeader = "-----BEGIN PUBLIC KEY-----" // 之前RSA2text函數里面的頭尾標識,這個是公鑰的
      const pemFooter = "-----END PUBLIC KEY-----"
      const pemContents = pub.substring(pemHeader.length, pub.length - pemFooter.length) // 去除pem頭尾
      // base64解碼
      const binaryDer = window.atob(pemContents)
      // 轉為ArrayBuffer二進制字符串
      const binary = str2ab(binaryDer)
      window.crypto.subtle.importKey(
          "spki", // 這邊如果私鑰則是pkcs8
          binary , 
          {
              name: "RSA-OAEP",
              hash: "SHA-512" // 保持一致
          },
          true, 
          ["encrypt"] // 用于加密所以是公鑰,私鑰就是decrypt
      )
      
      function str2ab(str) {
          const buf = new ArrayBuffer(str.length)
          const bufView = new Uint8Array(buf)
          for (let i = 0, strLen = str.length; i < strLen; i++) {
              bufView[i] = str.charCodeAt(i)
          }
          return buf
      }
      

      加密解密

      加密crypto.subtle.encrypt(algorithm, key, data),其中:
      1.algorithm,加解密只支持RSA-OAEP不支持RSAES-PKCS1-v1_5

      2.key即公鑰的CryptoKey對象

      3.data是一個BufferSource對象,不能直接是要加密的字符串。
      結果是一個ArrayBuffer,可以使用window.btoa(String.fromCharCode(...new Uint8Array(e)))輸出為base64字符串

      const enc = new TextEncoder()
      const data = enc.encode("sucks") // 這邊將要加密的字符串轉為utf-8的Uint8Array
      window.crypto.subtle.encrypt(
          {
              name: "RSA-OAEP"
          },
          publicKey, // 生成或者導入的CryptoKey對象
          data
      )
      

      解密crypto.subtle.decrypt(algorithm, key, data),基本同加密,這邊data對應為加密返回的ArrayBuffer,如果是base64字符串比如從后端加密過來的,就需要轉為Uint8Array。

      function base64ToUint8Array(base64String) {
          const padding = '='.repeat((4 - base64String.length % 4) % 4)
          const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/')
      
          const rawData = window.atob(base64)
          const outputArray = new Uint8Array(rawData.length)
      
          for (let i = 0; i < rawData.length; ++i) {
              outputArray[i] = rawData.charCodeAt(i)
          }
          return outputArray
      }
      

      返回值同加密

      posted @ 2024-08-03 14:20  charleschwang  閱讀(1966)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲欧美国产精品久久久久久久| 日本道之久夂综合久久爱| 被拉到野外强要好爽| 国产精品视频全国免费观看| 精品视频福利| 色综合久久综合中文综合网| 日韩精品国产另类专区| 日韩在线视频一区二区三| 欧美高清freexxxx性| 精品国产中文字幕在线| 伊人久久大香线蕉AV网禁呦| 宁津县| 成年女人片免费视频播放A| 国产成人无码专区| 久青草视频在线免费观看| 国产不卡一区二区四区| 国产av永久无码天堂影院| 国产精品成人免费视频网站京东| 悠悠色成人综合在线观看| 又黄又爽又色的免费网站| 国产免费网站看v片元遮挡| 青青草一区二区免费精品| 午夜夜福利一区二区三区| A毛片终身免费观看网站| 中文字幕国产在线精品| 日本一区二区三区在线播放| 最新亚洲人成网站在线影院| 久久午夜电影网| 久久AV中文综合一区二区| 久久国产精99精产国高潮| 亚洲国产成人va在线观看天堂| 日韩V欧美V中文在线| 亚洲另类丝袜综合网| 亚洲人成电影网站 久久影视| 亚洲综合另类小说色区一| 欧美激情 亚洲 在线| 91精品乱码一区二区三区| 国产一级区二级区三级区| 婷婷六月综合缴情在线| 成人午夜在线播放| 久久久无码精品国产一区|