【问题标题】:JavaScript AES encryption and decryption (Advanced Encryption Standard)JavaScript AES 加解密(高级加密标准)
【发布时间】:2019-01-02 23:43:35
【问题描述】:

如何在 JavaScript 中使用 AES(高级加密标准)实现加密和解密。

为什么选择 AES(高级加密标准)?

安全性:与其他提交的密码相比,竞争算法将根据其抵抗攻击的能力来判断,尽管安全强度被认为是竞争中最重要的因素。

成本:旨在在全球、非排他性和免版税的基础上发布,候选算法将在计算和内存效率方面进行评估。

【问题讨论】:

    标签: javascript encryption aes


    【解决方案1】:

    function encrypt(message = '', key = ''){
        var message = CryptoJS.AES.encrypt(message, key);
        return message.toString();
    }
    function decrypt(message = '', key = ''){
        var code = CryptoJS.AES.decrypt(message, key);
        var decryptedMessage = code.toString(CryptoJS.enc.Utf8);
    
        return decryptedMessage;
    }
    console.log(encrypt('Hello World'));
    console.log(decrypt('U2FsdGVkX1/0oPpnJ5S5XTELUonupdtYCdO91v+/SMs='))
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>

    【讨论】:

    • 这个的 PHP 版本是什么。换句话说,您将在 PHP 中使用什么来解密和加密使用您发布的代码加密或解密的字符串
    【解决方案2】:

    为什么要在 JavaScript 中实现 AES?与本机(或 wasm)实现相比,它会非常慢。幸运的是,您可以访问a native implementation right in the browser(如果您更改了一些内容,甚至可以访问 IE11)。它非常快(根据some benchmarks posted a while ago on the Webkit blog,它快了数百倍)并且不需要 50kb 的库。

    在本例中使用 GCM,但如果您不需要身份验证,则可以使用 CTR 模式:

    const key = await crypto.subtle.generateKey({name: 'AES-GCM', length: 128}, true, ['encrypt', 'decrypt'])
    const text = "confidential message"
    // IV must be the same length (in bits) as the key
    const iv = await crypto.getRandomValues(new Uint8Array(16))
    const cyphertext = await crypto.subtle.encrypt({name: 'AES-GCM', tagLength: 32, iv}, key, new TextEncoder().encode(text))
    

    这将导致cyphertext 包含一个带有加密字符串和一个 4 字节身份验证标签的 ArrayBuffer(这是 GCM 特有的,其他 AES 模式只会产生加密数据)。只要您拥有用于加密的密钥和 IV,您就可以同样轻松地对其进行解密。

    const cleartext = await crypto.subtle.decrypt({name: 'AES-GCM', tagLength: 32, iv}, key, cyphertext)
    console.log(new TextDecoder().decode(cleartext))
    

    【讨论】:

    • "为什么要在 JavaScript 中实现 AES?"对我来说,这是因为我必须在 PostMan 收集脚本中进行 AES 解密。另一个用例可能是聊天应用或类似应用的两个实例之间的端到端加密。
    • 啊,是的,Postman 无法运行 WebAssembly 并且没有 WebCrypto API。不过,它确实内置了 crypto-js。您的其他示例还假设聊天应用程序具有像 Postman 的蹩脚的 JavaScript 运行时。大多数支持 JavaScript 的应用程序要么使用本机操作系统的 Web 视图引擎(因此您可以同时获得 WASM 和 WebCrypto),或者(希望不会完全过时)V8,例如 Electron 应用程序,这意味着至少是 WebAssembly。
    【解决方案3】:

    AES 是一种非常简单而强大的加密和解密方法。请看我下面的例子,它很容易在你准备好的代码中使用。

    只需调用encryptMessagedecryptMessage 函数即可。我已经在下面提供了运行示例。

    如何调用这些方法:

    code.encryptMessage('Welcome to AES !','your_password');
    code.decryptMessage('U2FsdGVkX1/S5oc9WgsNyZb8TJHsuL7+p4yArjEpOCYgDTUdkVxkmr+E+NdJmro9','your_password')
    

    let code = (function(){
        return{
          encryptMessage: function(messageToencrypt = '', secretkey = ''){
            var encryptedMessage = CryptoJS.AES.encrypt(messageToencrypt, secretkey);
            return encryptedMessage.toString();
          },
          decryptMessage: function(encryptedMessage = '', secretkey = ''){
            var decryptedBytes = CryptoJS.AES.decrypt(encryptedMessage, secretkey);
            var decryptedMessage = decryptedBytes.toString(CryptoJS.enc.Utf8);
    
            return decryptedMessage;
          }
        }
    })();
    
    console.log(code.encryptMessage('Welcome to AES !','your_password'));
    console.log(code.decryptMessage('U2FsdGVkX1/S5oc9WgsNyZb8TJHsuL7+p4yArjEpOCYgDTUdkVxkmr+E+NdJmro9','your_password'))
    <!DOCTYPE html>
    <html>
    <head>
    	<title>E2EE</title>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
    </head>
    <body>
    
    </body>
    </html>

    您也可以参考我的 github 代码库以获取更多参考。

    https://github.com/shedagemayur/JavaScriptCode/tree/master/AES

    【讨论】:

    • 正常工作。
    • 在将密钥从客户端发送到服务器之前,有没有办法隐藏密钥?可以在客户端的捆绑包中看到此密钥。所以想知道我们是否可以在客户端隐藏这个密钥?
    【解决方案4】:

    如果你正在构建一个 react 或 nodejs 应用程序,你可以简单地使用这个库 ncrypt-js 来加密和解密你的数据。

    See example on codesandbox

    用法:

    es5

    var ncrypt = require('ncrypt-js'); // or var { encrypt, decrypt } = require('ncrypt-js);
    
    let encryptData = ncrypt.encrypt('super secret data', 'secret_key');
    // or
    // let encryptData = encrypt('super secret data', 'secret_key');
    
    console.log(encryptData); // 11ab949601eb136f58ac3fe846e30d76.f9ce133b20adc35eef32af95957547abbb6fbfc5cb91cd14f5b0a088bd031883963cde1a56fd62fe2aeb75451a065d21
    var decryptedData = ncrypt.decrypt(encryptData);
    // or
    // var decryptedData = decrypt(encryptData);
    
    console.log(decryptedData); // super secret data
    

    es6

    import ncrypt from 'ncrypt-js'; // or import { encrypt, decrypt } from 'ncrypt-js';
    
    const encryptData = ncrypt.encrypt('super secret data', 'secret_key');
    // or
    // const encryptData = encrypt('super secret data', 'secret_key');
    
    console.log(encryptData); // 11ab949601eb136f58ac3fe846e30d76.f9ce133b20adc35eef32af95957547abbb6fbfc5cb91cd14f5b0a088bd031883963cde1a56fd62fe2aeb75451a065d21
    const decryptedData = ncrypt.decrypt(encryptData);
    // or
    // const decryptedData = decrypt(encryptData);
    
    console.log(decryptedData); // super secret data
    

    【讨论】:

      【解决方案5】:

      我已经构建了一个名为 encrypt-with-password 的 NPM 包,它允许您使用密码加密和解密文本和 JavaScript 对象,使用 AES 并使用 PBDKF2 从密码中派生 AES 密钥。

      安装:

      npm install encrypt-with-password
      

      或:

      yarn add encrypt-with-password
      

      加密和解密文本:

      const encryptpwd = require('encrypt-with-password');
      
      const text = 'Hello, World!';
      const password = 'examplepassword';
      
      const encrypted = encryptpwd.encrypt(text, password); // ---> this is the encrypted (output) value
      
      // example encrypted value: 'e68e7ccd9e908665818a49f111c342ed:c9b83ff7624bb3b26af8cc853d61cd2f7959cecc4308383c39a0924e90637889'
      
      const decrypted = encryptpwd.decrypt(encrypted, password) // ---> this decrypts the encrypted value and yields the original text
      

      加密和解密 JavaScript 对象:

      const encryptpwd = require('encrypt-with-password');
      
      const jsObject = {
        aString: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.',
        aNumber: 5,
        anArray: [1, 2, 3, 4, 5],
        anObj: {
          aKey: 'a value'
        }
      };
      const password = 'examplepassword2';
      
      const encrypted = encryptpwd.encryptJSON(jsObject, password); // ---> this is the encrypted value
      
      // example encrypted value: 'f953284ffe3e44a7b9de8487b50c3449:123378b5c481399488f520ebb774b076b85a12bc0f9a67cf8faf359eb4f804fc0594bc42374a20b4216b1312d7a408cf94517e19dfcada5513c49f6d13d26c982c562904306900a3f777b9c19b9c002e12dd216984f68566684f9f0259a45e007a0cecb2325333faafb18ed0e751933d8b1195b02b2adda29269cf1c6fa6fff73f0bac4abcf58b391521e0382c06a5f01f31c1243d827f8c7076f81d7f530259a3ae459e524bee80230672f153ab6a4e'
      
      const decrypted = encryptpwd.decryptJSON(encrypted, password) // ---> this decrypts the encrypted value and yields the original object
      

      这个包背后的代码是开源的:https://github.com/xtrp/encrypt-with-password

      【讨论】:

        【解决方案6】:

        下面的代码对我有用

        encryptMessage: function(messageToencrypt = '', secretkey = ''){
            var encryptedMessage = CryptoJS.AES.encrypt(messageToencrypt, secretkey);
            return encryptedMessage.toString();
        },
        decryptMessage: function(encryptedMessage = '', secretkey = ''){
            var decryptedBytes = CryptoJS.AES.decrypt(encryptedMessage, secretkey);
            var decryptedMessage = decryptedBytes.toString(CryptoJS.enc.Utf8);
        
            return decryptedMessage;
        }
        

        谢谢

        【讨论】:

          猜你喜欢
          • 2017-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-24
          • 2016-09-22
          • 1970-01-01
          • 2015-01-20
          • 2014-01-05
          相关资源
          最近更新 更多