首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AES-GCM解密拒绝承诺

AES-GCM解密拒绝承诺
EN

Stack Overflow用户
提问于 2017-09-25 01:12:58
回答 1查看 1.2K关注 0票数 2

我有一个字符串,我想使用JavaScript网络密码API用AES-GCM加密。我可以加密它,但是当我解密它时,承诺会被拒绝,并且我不会得到一个不同的描述性错误消息。

代码语言:javascript
复制
    function aes_encrypt(key, IV, data){
        return new Promise(function(resolve, reject){
            window.crypto.subtle.encrypt(
            {
                name: "AES-GCM",

                //Don't re-use initialization vectors!
                //Always generate a new iv every time your encrypt!
                //Recommended to use 12 bytes length
                iv: sta(IV),

                //Tag length (optional)
                tagLength: 128, //can be 32, 64, 96, 104, 112, 120 or 128 (default)
            },
            key, //from generateKey or importKey above
            sta(data) //ArrayBuffer of data you want to encrypt
            )
            .then(function(encrypted){
                //returns an ArrayBuffer containing the encrypted data
                resolve(ats(encrypted));
            })
            .catch(function(err){
                console.error(err);
            });
        });
    }

    function aes_decrypt(key, IV, data){
        return new Promise(function(resolve, reject){
            window.crypto.subtle.decrypt(
            {
                name: "AES-GCM",
                iv: sta(IV), //The initialization vector you used to encrypt
                tagLength: 128 //The tagLength you used to encrypt (if any)
            },
            key, //from generateKey or importKey above
            sta(data) //ArrayBuffer of the data
            )
            .then(function(decrypted){
                //returns an ArrayBuffer containing the decrypted data
                alert(decrypted);
                resolve(ats(new Uint8Array(decrypted)));
                //resolve(ats(decrypted));
            })
            .catch(function(err){
                console.error(err);
            });
        });
    }



    function ecdh_generate_keypair(){
        return new Promise(function(resolve, reject){
            window.crypto.subtle.generateKey(
                {
                    name: "ECDH",
                    namedCurve: "P-384" //can be "P-256", "P-384", or "P-521"
                },
                true, //whether the key is extractable (i.e. can be used in exportKey)
                ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
            )
            .then(function(key){
                //returns a keypair object
                resolve(key);
            })
            .catch(function(err){
                console.error(err);
            });
        });
    }

    function ecdh_export(key){
        return new Promise(function(resolve, reject){
            window.crypto.subtle.exportKey(
                "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
                key //can be a publicKey or privateKey, as long as extractable was true
            )
            .then(function(keydata){
                //returns the exported key data
                resolve(keydata);
            })
            .catch(function(err){
                console.error(err);
            });
        });
    }

    function ecdh_import(key){
        return new Promise(function(resolve, reject){
            window.crypto.subtle.importKey(
                "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
                key,
                {   //these are the algorithm options
                    name: "ECDH",
                    namedCurve: "P-384", //can be "P-256", "P-384", or "P-521"
                },
                true, //whether the key is extractable (i.e. can be used in exportKey)
                ["deriveKey", "deriveBits"] //"deriveKey" and/or "deriveBits" for private keys only (just put an empty list if importing a public key)
            )
            .then(function(privateKey){
                //returns a privateKey (or publicKey if you are importing a public key)
                resolve(privateKey);
            })
            .catch(function(err){
                console.error(err);
            });
        });
    }

    function ecdh_derive_key(pub, priv){
        return new Promise(function(resolve, reject){
            window.crypto.subtle.deriveKey(
            {
                name: "ECDH",
                namedCurve: "P-384", //can be "P-256", "P-384", or "P-521"
                public: pub, //an ECDH public key from generateKey or importKey
            },
            priv, //your ECDH private key from generateKey or importKey
            { //the key type you want to create based on the derived bits
                name: "AES-GCM", //can be any AES algorithm ("AES-CTR", "AES-GCM", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
                //the generateKey parameters for that type of algorithm
                length: 256, //can be  128, 192, or 256
            },
            true, //whether the derived key is extractable (i.e. can be used in exportKey)
            ["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
            )
            .then(function(keydata){
                //returns the exported key data
                resolve(keydata);
            })
            .catch(function(err){
                console.error(err);
            });
        });
    }

    function random_characters(amount){
        var text = "";
        var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        for (var i = 0; i < amount; i++){
            text += possible.charAt(Math.floor(Math.random() * possible.length));
        }

        return text;
    }

    // string-to-arraybuffer
    function sta(data){
        var enc = new TextEncoder("utf-8");
        return enc.encode(data);
    }

    // arraybuffer-to-string
    function ats(data){
        var enc = new TextDecoder();
        return enc.decode(data);
    }

    // JSON into and out of the database for cryptokeys
    function json_compress(obj){
        var s = JSON.stringify(obj);
        s = s.replace(/,/g, "♀");
        s = s.replace(/{/g, "☺");
        s = s.replace(/}/g, "☻");
        return s;
    }
    function json_decompress(str){
        str = str.replace(/♀/g, ",");
        str = str.replace(/☺/g, "{");
        str = str.replace(/☻/g, "}");
        return JSON.parse(str);
    }

    ecdh_generate_keypair().then(function(key){
        ecdh_generate_keypair().then(function(key2){
            ecdh_derive_key(key2.publicKey, key.privateKey).then(function(aeskey){
                var m = "Hello World!";
                aes_encrypt(aeskey, "abcdefghijkl", m).then(function(c){
                    alert(c);
                    aes_decrypt(aeskey, "abcdefghijkl", c).then(function(r){
                        alert(r);
                    });
                });
            });
        });
    });

我知道对AES的IV进行硬编码是一种安全风险,但我只是想让它用于测试目的。你能提供的任何帮助都是非常感谢的,因为这已经困扰了我一整天。提前感谢!

编辑:添加Chrome调试错误消息

代码语言:javascript
复制
cryptofunctions.js:48 DOMException
(anonymous) @ cryptofunctions.js:48
Promise rejected (async)
(anonymous) @ cryptofunctions.js:47
aes_decrypt @ cryptofunctions.js:31
(anonymous) @ cryptofunctions.js:184
Promise resolved (async)
(anonymous) @ cryptofunctions.js:182
Promise resolved (async)
(anonymous) @ cryptofunctions.js:180
Promise resolved (async)
(anonymous) @ cryptofunctions.js:179
Promise resolved (async)
(anonymous) @ cryptofunctions.js:178

编辑2:决定张贴整个文件,因为这一切似乎与问题有关。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-25 02:38:45

例外-当遇到下列例外时,拒绝承诺: 当请求的操作对所提供的密钥无效时(例如,无效加密算法或指定加密算法的无效密钥)时,InvalidAccessError。

encrypted调用时将resolve()传递给resolve(),在aes_decrypt()调用时传递data而不是sta(data),因为data已经是aes_decrypt函数中的ArrayBuffer

代码语言:javascript
复制
function aes_encrypt(key, IV, data) {
  return window.crypto.subtle.encrypt({
        name: "AES-GCM",

        //Don't re-use initialization vectors!
        //Always generate a new iv every time your encrypt!
        //Recommended to use 12 bytes length
        iv: sta(IV),

        //Tag length (optional)
        tagLength: 128, //can be 32, 64, 96, 104, 112, 120 or 128 (default)
      },
      key, //from generateKey or importKey above
      sta(data) //ArrayBuffer of data you want to encrypt
    )
    .then(function(encrypted) {
      //returns an ArrayBuffer containing the encrypted data
      return encrypted;
    })
    .catch(function(err) {
      console.error(err);
    });
}

function aes_decrypt(key, IV, data) {
  return window.crypto.subtle.decrypt({
        name: "AES-GCM",
        iv: sta(IV), //The initialization vector you used to encrypt
        tagLength: 128 //The tagLength you used to encrypt (if any)
      },
      key, //from generateKey or importKey above
      data //ArrayBuffer of the data
    )
    .then(function(decrypted) {
      //returns an ArrayBuffer containing the decrypted data
      // alert(decrypted);
      return ats(new Uint8Array(decrypted));
      //resolve(ats(decrypted));
    })
    .catch(function(err) {
      console.error(err);
    });
}



function ecdh_generate_keypair() {
  return window.crypto.subtle.generateKey({
        name: "ECDH",
        namedCurve: "P-384" //can be "P-256", "P-384", or "P-521"
      },
      true, //whether the key is extractable (i.e. can be used in exportKey)
      ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
    )
    .then(function(key) {
      //returns a keypair object
      return key;
    })
    .catch(function(err) {
      console.error(err);
    });
}

function ecdh_export(key) {
  return window.crypto.subtle.exportKey(
      "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
      key //can be a publicKey or privateKey, as long as extractable was true
    )
    .then(function(keydata) {
      //returns the exported key data
      return keydata;
    })
    .catch(function(err) {
      console.error(err);
    });
}

function ecdh_import(key) {
  return window.crypto.subtle.importKey(
      "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
      key, { //these are the algorithm options
        name: "ECDH",
        namedCurve: "P-384", //can be "P-256", "P-384", or "P-521"
      },
      true, //whether the key is extractable (i.e. can be used in exportKey)
      ["deriveKey", "deriveBits"] //"deriveKey" and/or "deriveBits" for private keys only (just put an empty list if importing a public key)
    )
    .then(function(privateKey) {
      //returns a privateKey (or publicKey if you are importing a public key)
      return privateKey;
    })
    .catch(function(err) {
      console.error(err);
    });
}

function ecdh_derive_key(pub, priv) {
  return window.crypto.subtle.deriveKey({
        name: "ECDH",
        namedCurve: "P-384", //can be "P-256", "P-384", or "P-521"
        public: pub, //an ECDH public key from generateKey or importKey
      },
      priv, //your ECDH private key from generateKey or importKey
      { //the key type you want to create based on the derived bits
        name: "AES-GCM", //can be any AES algorithm ("AES-CTR", "AES-GCM", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
        //the generateKey parameters for that type of algorithm
        length: 256, //can be  128, 192, or 256
      },
      true, //whether the derived key is extractable (i.e. can be used in exportKey)
      ["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
    )
    .then(function(keydata) {
      //returns the exported key data
      return keydata;
    })
    .catch(function(err) {
      console.error(err);
    });
}

function random_characters(amount) {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < amount; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  return text;
}

// string-to-arraybuffer
function sta(data) {
  var enc = new TextEncoder("utf-8");
  return enc.encode(data);
}

// arraybuffer-to-string
function ats(data) {
  var enc = new TextDecoder();
  return enc.decode(data);
}

// JSON into and out of the database for cryptokeys
function json_compress(obj) {
  var s = JSON.stringify(obj);
  s = s.replace(/,/g, "♀");
  s = s.replace(/{/g, "☺");
  s = s.replace(/}/g, "☻");
  return s;
}

function json_decompress(str) {
  str = str.replace(/♀/g, ",");
  str = str.replace(/☺/g, "{");
  str = str.replace(/☻/g, "}");
  return JSON.parse(str);
}

ecdh_generate_keypair().then(function(key) {
  ecdh_generate_keypair().then(function(key2) {
    ecdh_derive_key(key2.publicKey, key.privateKey).then(function(aeskey) {
      var m = "Hello World!";
      aes_encrypt(aeskey, "abcdefghijkl", m).then(function(c) {
        // alert(c);
        aes_decrypt(aeskey, "abcdefghijkl", c).then(function(r) {
          alert(r);
        });
      });
    });
  });
});

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46396345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档