Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用AES密钥包装RSA私钥,然后展开_Javascript_Encryption_Cryptography_Webcrypto Api - Fatal编程技术网

Javascript 使用AES密钥包装RSA私钥,然后展开

Javascript 使用AES密钥包装RSA私钥,然后展开,javascript,encryption,cryptography,webcrypto-api,Javascript,Encryption,Cryptography,Webcrypto Api,我一直在尝试对使用Web加密API生成的RSA私钥进行密码保护。为此, 我首先生成一个RSA密钥对 然后,我从密码中导出AES对称密钥 然后我用步骤2中的AES密钥包装步骤1中的RSA私钥 完成后,我会立即将所有这些信息传递给unwrap方法,在该方法中我会尝试将其展开,以验证其是否有效 代码如下: <html> <script> function wrap(password) { var iterations = 1000000; // Utility fu

我一直在尝试对使用Web加密API生成的RSA私钥进行密码保护。为此,

  • 我首先生成一个RSA密钥对
  • 然后,我从密码中导出AES对称密钥
  • 然后我用步骤2中的AES密钥包装步骤1中的RSA私钥
  • 完成后,我会立即将所有这些信息传递给
    unwrap
    方法,在该方法中我会尝试将其展开,以验证其是否有效

  • 代码如下:

    <html>
    <script>
    function wrap(password) {
      var iterations = 1000000;
    
      // Utility function
      var stringToByteArray = function(s){
        if ("TextEncoder" in window) {
          encoder = new window.TextEncoder;
          return encoder.encode(s);
        }
        var result = new Uint8Array(s.length);
        for (var i=0; i<s.length; i++){
            result[i] = s.charCodeAt(i);
        }
        return result;
      }
    
      var saltBytes = stringToByteArray("NaCl");
      var passphraseBytes = stringToByteArray(password);
    
      return crypto.subtle.generateKey({
        name: "RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([1, 0, 1]),
        hash: {name: "SHA-256"}
      }, true, ["encrypt", "decrypt"]).then(function(keyPair) {
        return crypto.subtle.importKey(
          "raw", passphraseBytes, {name: "PBKDF2"}, false, ["deriveKey"]
        ).then(function(baseKey) {
          return window.crypto.subtle.deriveKey(
            {name: "PBKDF2", salt: saltBytes, iterations: iterations, hash: "SHA-1"},
            baseKey,
            {name: "AES-CBC", length: 256},
            false,
            ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
          ).then(function(wrapperKey) {
            var iv = crypto.getRandomValues(new Uint8Array(16));
            return crypto.subtle.wrapKey(
              "pkcs8",
              keyPair.privateKey,
              wrapperKey,
              {name: "AES-CBC", iv: iv }
            ).then(function(wrappedKey) {
              return {
                iv: iv,
                wrapper: wrapperKey,
                wrapped: wrappedKey
              }
            })
          });
        }).catch(function(err) {
          console.log(err);
        });
      })
    }
    
    
    function unwrap(account) {
      console.log(account);
      crypto.subtle.unwrapKey(
        "pkcs8",
        account.wrapped,
        account.wrapper,
        {
          name: "AES-CBC",
          iv: account.iv
        },
        {
          name: "RSA-OAEP",
          modulusLength: 2048,
          publicExponent: new Uint8Array([1, 0, 1]),
          hash: {name: "SHA-256"}
        },
        true,
        ['decrypt', 'encrypt']
      ).then(function(privateKey) {
        console.log("unwrapped = ", privateKey);
      }).catch(function(e) {
        console.log(e)
      })
    }
    
    // Finally I call "wrap" and then "unwrap"
    wrap("password").then(unwrap)
    
    </script>
    </html>
    

    在过去的24小时里,我一直在拼命工作,因为我不能让它工作。有人能发现问题吗?这是一段完全独立的代码,因此您可以通过复制并粘贴到HTML文件并在浏览器中打开来尝试它。

    您试图做的是,使用对称密钥包装公钥/私钥,而不是包装/展开的工作方式

    • wrapKey
      ,允许密钥包装对称的密钥以供使用 (传输、存储)在不安全的环境中
    • unwrapKey
      ,允许 打开对称密钥以在中使用(传输、存储)的密钥 不安全的环境
    可以包装/展开对称密钥,但不能包装/展开公钥/私钥对(或密钥),因为包装/展开可能希望包装的密钥是对称密钥而不是非对称密钥

    SubtleCrypto.wrapKey()
    方法返回一个包装的 对称用于在不安全环境中使用(传输、存储)的密钥。 返回的包装缓冲区采用参数中给定的格式,并且 包含由给定包装密钥包装的密钥 算法

    sublecrypto.unwrapKey()
    方法返回加密密钥的承诺 对应于参数中给定的已包装密钥


    如果你是根据Mozilla文档说话的,我不相信他们的WebCryptoAPI,因为我知道他们的文档不完整,有时甚至会误导,至少对WebCryptoAPI是这样。最初的W3C提案没有任何这样的限制,规范说它只是一种加密机制。另外,自从我问了这个问题之后,我发现了一个可以实现这一点的库,这就是Mozilla文档,这确实是当前大多数(所有?)主流浏览器的状态。正如你所说,W3C也没有限制包装。然而。。。以上是通过broswer API为开发人员提供的内容。很好,您找到了一个实现您的需求的解决方案。总而言之:MBC的糟糕实施。。。(主要浏览器联盟)。。。新年快乐!
    DOMException: Cannot create a key using the specified key usages.