如何使用AES

编程入门 行业动态 更新时间:2024-10-19 00:23:43
如何使用AES-GCM进行C#.NET加密()然后JS WebCryptoApi decrypt()?(How to C#.NET encrypt() then JS WebCryptoApi decrypt() using AES-GCM?)

我想使用C#加密数据并使用JS解密它。

此表表明AES-GCM是使用WebCryptoApi https://diafygi.github.io/webcrypto-examples/的方法 。

我成功地使用BouncyCastle https://codereview.stackexchange.com/questions/14892/simplified-secure-encryption-of-a-string在.NET中加密(和解密)。

 var message = "This is the test message";
 var key = AESGCM.NewKey();
 Console.Out.WriteLine("KEY:" + Convert.ToBase64String(key));
 >> KEY:5tgX6AOHot1T9SrImyILIendQXwfdjfOSRAVfMs0ed4=
 string encrypted = AESGCM.SimpleEncrypt(message, key);
 Console.Out.WriteLine("ENCRYPTED:" + encrypted);
 >>  ENCRYPTED:Ct0/VbOVsyp/LMxaaFqKKw91+ts+8uzDdHLrTG1XVjPNL7KiBGYB4kfdNGl+xj4fYqdb4JXgdTk=
 var decrypted = AESGCM.SimpleDecrypt(encrypted, key);
 Console.Out.WriteLine("DECRYPTED:" + decrypted);
 >> DECRYPTED:This is the test message
 

但是,我无法弄清楚如何解密这个客户端。 在https://github.com/diafygi/webcrypto-examples#aes-cbc---decrypt上有很多WebCryptoApi示例,包括AES-GCM。

第一步(似乎工作)是导入密钥,我有一个base-64编码的字符串:

var keyString = "+6yDdIiJJl8Lqt60VOHuP25p4yNxz0CRMoE/WKA+Mqo=";

function _base64ToArrayBuffer(base64) {
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
}

var key = _base64ToArrayBuffer(keyString )
var cryptoKey; // we'll get this out in the promise below
window.crypto.subtle.importKey(
    "raw",
    key,
    {   //this is the algorithm options
        name: "AES-GCM",
    },
    true, // whether the key is extractable
    ["encrypt", "decrypt"] // usages
)
.then(function(key){
    //returns the symmetric key
    console.log(key); 
    cryptoKey = key;
})
.catch(function(err){
    console.error(err);
});
 

最后一步应该是解密编码消息,该消息也是base-64编码的字符串

var encryptedString = "adHb4UhM93uWyRIV6L1SrYFbxEpIbj3sQW8VwJDP7v+XoxGi6fjmucEEItP1kQWxisZp3qhoAhQ=";
var encryptedArrayBuffer = _base64ToArrayBuffer(encryptedString)
window.crypto.subtle.decrypt(
    {
        name: "AES-GCM",
        iv: new ArrayBuffer(12), //The initialization vector you used to encrypt
        //additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any)
       // tagLength: 128, //The tagLength you used to encrypt (if any)
    },
    cryptoKey, //from above
    encryptedArrayBuffer //ArrayBuffer of the data
)
.then(function(decrypted){
    //returns an ArrayBuffer containing the decrypted data
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    debugger; console.error(err);
});
 

不幸的是,这是一个DomError。

我不知道我应该在解密方法中使用“iv”。 我试过null,ArrayBuffer(0),ArrayBuffer(12)。 这几乎是我的理解结束的地方。

I want to encrypt data using C# and decrypt it using JS.

This table suggests that AES-GCM is the way to go with WebCryptoApi https://diafygi.github.io/webcrypto-examples/.

I am successfully using BouncyCastle https://codereview.stackexchange.com/questions/14892/simplified-secure-encryption-of-a-string to encrypt (and decrypt) in .NET.

 var message = "This is the test message";
 var key = AESGCM.NewKey();
 Console.Out.WriteLine("KEY:" + Convert.ToBase64String(key));
 >> KEY:5tgX6AOHot1T9SrImyILIendQXwfdjfOSRAVfMs0ed4=
 string encrypted = AESGCM.SimpleEncrypt(message, key);
 Console.Out.WriteLine("ENCRYPTED:" + encrypted);
 >>  ENCRYPTED:Ct0/VbOVsyp/LMxaaFqKKw91+ts+8uzDdHLrTG1XVjPNL7KiBGYB4kfdNGl+xj4fYqdb4JXgdTk=
 var decrypted = AESGCM.SimpleDecrypt(encrypted, key);
 Console.Out.WriteLine("DECRYPTED:" + decrypted);
 >> DECRYPTED:This is the test message
 

But, I can't figure out how to decrypt this client side. There's a great list of WebCryptoApi examples including AES-GCM at https://github.com/diafygi/webcrypto-examples#aes-cbc---decrypt.

First step (which seems to working) is to import the key, which I have as a base-64 encoded string:

var keyString = "+6yDdIiJJl8Lqt60VOHuP25p4yNxz0CRMoE/WKA+Mqo=";

function _base64ToArrayBuffer(base64) {
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
}

var key = _base64ToArrayBuffer(keyString )
var cryptoKey; // we'll get this out in the promise below
window.crypto.subtle.importKey(
    "raw",
    key,
    {   //this is the algorithm options
        name: "AES-GCM",
    },
    true, // whether the key is extractable
    ["encrypt", "decrypt"] // usages
)
.then(function(key){
    //returns the symmetric key
    console.log(key); 
    cryptoKey = key;
})
.catch(function(err){
    console.error(err);
});
 

The final step should be to decrypt the encoded message, which is also a base-64 encoded string

var encryptedString = "adHb4UhM93uWyRIV6L1SrYFbxEpIbj3sQW8VwJDP7v+XoxGi6fjmucEEItP1kQWxisZp3qhoAhQ=";
var encryptedArrayBuffer = _base64ToArrayBuffer(encryptedString)
window.crypto.subtle.decrypt(
    {
        name: "AES-GCM",
        iv: new ArrayBuffer(12), //The initialization vector you used to encrypt
        //additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any)
       // tagLength: 128, //The tagLength you used to encrypt (if any)
    },
    cryptoKey, //from above
    encryptedArrayBuffer //ArrayBuffer of the data
)
.then(function(decrypted){
    //returns an ArrayBuffer containing the decrypted data
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    debugger; console.error(err);
});
 

Unfortunately, this is thowing a DomError.

I have no idea what I am supposed to use for "iv" in the decrypt method. I've tried null, ArrayBuffer(0), ArrayBuffer(12). This is pretty much where my understanding ends.

最满意答案

如果你研究AESGCM的实现,你应该看到nonce(称为IV)是密文的一部分。 其大小设置为16个字节( NonceBitSize = 128 )。 您需要从JavaScript中的密文开头读取那么多字节,并使用剩余的字节作为要解密的实际密文。

GCM仅定义为96位的随机数,因此您可能需要将其更改为NonceBitSize = 96并读取前12个字节。

根据这个答案 ,您需要为认证标签切片密文的最后16个字节( MacBitSize = 128 )。

96位随机数的示例:

window.crypto.subtle.decrypt( { name: "AES-GCM", iv: encryptedArrayBuffer.slice(0, 12), //The initialization vector you used to encrypt //additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any) // tagLength: 128, //The tagLength you used to encrypt (if any) tag: encryptedArrayBuffer.slice(-16), // authentication tag }, cryptoKey, //from above encryptedArrayBuffer.slice(12, -16) //ArrayBuffer of the data // alternatively: encryptedArrayBuffer.slice(12) // in some cases leave the authentication tag in place )

If you look into the implementation of AESGCM, you should see that the nonce (called IV) is part of the ciphertext. Its size is set to 16 bytes (NonceBitSize = 128). You would need to read that many bytes from the beginning of the ciphertext in JavaScript and use the remaining bytes as the actual ciphertext to be decrypted.

GCM is only defined for a nonce of 96 bit, so you might need to change it to NonceBitSize = 96 and read the first 12 bytes.

Based on this answer, you will need to slice the last 16 bytes of the ciphertext (MacBitSize = 128) for the authentication tag.

Example with a 96 bit nonce:

window.crypto.subtle.decrypt( { name: "AES-GCM", iv: encryptedArrayBuffer.slice(0, 12), //The initialization vector you used to encrypt //additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any) // tagLength: 128, //The tagLength you used to encrypt (if any) tag: encryptedArrayBuffer.slice(-16), // authentication tag }, cryptoKey, //from above encryptedArrayBuffer.slice(12, -16) //ArrayBuffer of the data // alternatively: encryptedArrayBuffer.slice(12) // in some cases leave the authentication tag in place )

更多推荐

本文发布于:2023-04-28 03:15:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1329759.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   AES

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!