Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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-GCM对C#.NET加密()然后对JS WebCryptoApi解密()?_Javascript_C#_Cryptography_Bouncycastle_Webcrypto Api - Fatal编程技术网

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

Javascript 如何使用AES-GCM对C#.NET加密()然后对JS WebCryptoApi解密()?,javascript,c#,cryptography,bouncycastle,webcrypto-api,Javascript,C#,Cryptography,Bouncycastle,Webcrypto Api,我想用C#加密数据,用JS解密 此表表明AES-GCM是使用WebCryptoApi的方式 我正在成功地使用BouncyCastle在.NET中加密(和解密) var message=“这是测试消息”; var key=AESGCM.NewKey(); Console.Out.WriteLine(“KEY:+Convert.ToBase64String(KEY)); >>键:5tgX6AOHot1T9SrImyILIendQXwfdjfOSRAVfMs0ed4= 加密字符串=AESGCM.Sim

我想用C#加密数据,用JS解密

此表表明AES-GCM是使用WebCryptoApi的方式

我正在成功地使用BouncyCastle在.NET中加密(和解密)

var message=“这是测试消息”;
var key=AESGCM.NewKey();
Console.Out.WriteLine(“KEY:+Convert.ToBase64String(KEY));
>>键:5tgX6AOHot1T9SrImyILIendQXwfdjfOSRAVfMs0ed4=
加密字符串=AESGCM.SimpleEncrypt(消息、密钥);
Console.Out.WriteLine(“加密:“+加密”);
>>加密:Ct0/VbOVsyp/LMxaaFqKKw91+ts+8uzDdHLrTG1XVjPNL7KiBGYB4kfdNGl+xj4fYqdb4JXgdTk=
var decrypted=aesgm.simpledcrypt(加密,密钥);
Console.Out.WriteLine(“解密:+解密”);
>>解密:这是测试消息
但是,我不知道如何解密这个客户端。有一个很好的WebCryptoApi示例列表,包括AES-GCM

第一步(似乎有效)是导入密钥,我将其作为base-64编码字符串:

var keyString=“+6yddiijjjl8lqt60vohup25p4ynxz0crmoe/WKA+Mqo=”;
函数_base64ToArrayBuffer(base64){
var binary_string=window.atob(base64);
var len=二进制字符串长度;
var字节=新的Uint8Array(len);
对于(变量i=0;i
最后一步应该是解密编码的消息,它也是一个base-64编码的字符串

var encryptedString=“adHb4UhM93uWyRIV6L1SrYFbxEpIbj3sQW8VwJDP7v+XOxGI6FJmuceIP1KQWXiSZP3QHOAHQ=”;
var encryptedArrayBuffer=\u base64ToArrayBuffer(encryptedString)
window.crypto.division.decrypt(
{
名称:“AES-GCM”,
iv:new ArrayBuffer(12),//用于加密的初始化向量
//additionalData:ArrayBuffer,//用于加密的additionalData(如果有)
//tagLength:128,//用于加密的tagLength(如果有)
},
加密密钥,//来自上面
encryptedArrayBuffer//数据的ArrayBuffer
)
.then(函数(已解密){
//返回包含解密数据的ArrayBuffer
log(新的Uint8Array(已解密));
})
.catch(函数(err){
调试器;控制台.error(err);
});
不幸的是,这是一个错误


我不知道在解密方法中“iv”应该使用什么。我尝试了null、ArrayBuffer(0)、ArrayBuffer(12)。这几乎就是我的理解的终点。

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

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

基于,您将需要为身份验证标记分割密文的最后16个字节(
MacBitSize=128

具有96位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 
)

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

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

基于,您将需要为身份验证标记分割密文的最后16个字节(
MacBitSize=128

具有96位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 
)

如果只使用对称加密,则服务器和客户端需要完全相同的密钥。如果将加密密钥从服务器发送到客户端,或者以其他方式发送,则需要加密对称加密密钥。最简单的方法是使用TLS。如果您使用TLS,那么数据和密钥都是加密的,所以您不需要自己加密。这并没有提供任何安全性,只是有点模糊。你应该读到:是的,我们只是试图混淆:所谓的“DRM”。这太荒谬了。“策略”是混淆js中的解密,并让用户“难以”检查流量。然后,我们在浏览器中以清晰可见的方式向他们显示解密结果。当然,任何想走那么远的人都可以找到十几种其他方式来获取内容。我们将此与其他策略结合起来,构建一个美丽的多层荒谬蛋糕。我仍然想解决这个问题。如果你只使用对称加密,你需要在服务器和客户端使用完全相同的密钥。如果将加密密钥从服务器发送到客户端,或者以其他方式发送,则需要加密对称加密密钥。最简单的方法是使用TLS。如果您使用TLS,那么数据和密钥都是加密的,所以您不需要自己加密。这并没有提供任何安全性,只是有点模糊。你应该读到:是的,我们只是试图混淆:所谓的“DRM”。这太荒谬了。“策略”是混淆js中的解密,并让用户“难以”检查流量。然后我们向他们展示解密的结果