簡體   English   中英

如何使用AES-GCM將C#.NET加密()然后JS WebCryptoApi解密()?

[英]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上有很多包含AES-GCM的WebCryptoApi示例。

第一步(似乎可行)是導入密鑰,我將其作為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);
});

最后一步應該是解密編碼后的消息,該消息也是基於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)。 我的理解到此結束。

如果研究AESGCM的實現, AESGCM應該看到現時(稱為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 
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM