博兔

导航

dotnet AesGcm

dotnet的算法库实现了Gcm模式的加密算法,这里不讨论算法的原理,只是简单的使用功能。

注意:AesGcm对dotnet的版本要求,具体参考官方文档。

简单使用

 1 // The key parameter length is other than 16, 24, or 32 bytes
 2 var key = System.Text.Encoding.UTF8.GetBytes("2836e95fcd10e04b0069bb1ee6599528");
 3 var aes = new System.Security.Cryptography.AesGcm(key);
 4 
 5 var nonceByteSizes = System.Security.Cryptography.AesGcm.NonceByteSizes;
 6 Console.WriteLine($"nonce size max={nonceByteSizes.MaxSize} min={nonceByteSizes.MinSize}");
 7 
 8 var nonce = new byte[12];
 9 new Random().NextBytes(nonce);
10 
11 var plainttext = System.Text.Encoding.UTF8.GetBytes("这是一段待加密的内容");
12 var ciphertext = new byte[plainttext.Length];
13 
14 var tagByteSizes = System.Security.Cryptography.AesGcm.TagByteSizes;
15 Console.WriteLine($"tag size max={tagByteSizes.MaxSize} min={tagByteSizes.MinSize}");
16 
17 var tag = new byte[16];
18 aes.Encrypt(nonce, plainttext, ciphertext, tag);
19 aes.Decrypt(nonce, ciphertext, tag, plainttext);
20 
21 Console.WriteLine(System.Text.Encoding.UTF8.GetString(plainttext));

里面有几个关键的参数:

秘钥支持16位,24位,32位长度

nonce,也称为初始化向量(IV)长度是12位

tag,是加密后产生的内容,注意不是密文,代码中使用的长度是16位,可以通过TagByteSizes获取支持的值

执行结果:

nonce size max=12 min=12
tag size max=16 min=12
这是一段待加密的内容

在实际使用中,加密和解密过程是分开的。从代码中可以看出,如果想要解密,除了秘钥以外,还需要nonce,tag作为解密参数。

对于秘钥,加密方和解密方肯定是都知道的。

nonce其实也可以由双方事先约定好生成规则,保持一致就可以。

问题是tag,是在加密时生成的,无法通过事先约定的方式处理,需要和密文一起告诉对方。

我们可以这样定义,加密方加密后,将nonce,密文,tag拼接在一起,解密方按照该规则提取内容解密。nonce固定12位,tag使用16位。

 1 public static byte[] Encrypt(byte[] key, string content)
 2 {
 3     var aes = new System.Security.Cryptography.AesGcm(key);
 4 
 5     var nonce = new byte[12];
 6     new Random().NextBytes(nonce);
 7 
 8     var plainttext = System.Text.Encoding.UTF8.GetBytes(content);
 9     var ciphertext = new byte[plainttext.Length];
10 
11     var tag = new byte[16];
12     aes.Encrypt(nonce, plainttext, ciphertext, tag);
13 
14     var ret = new byte[nonce.Length + ciphertext.Length + tag.Length];
15     Buffer.BlockCopy(nonce, 0, ret, 0, nonce.Length);
16     Buffer.BlockCopy(ciphertext, 0, ret, nonce.Length, ciphertext.Length);
17     Buffer.BlockCopy(tag, 0, ret, nonce.Length + ciphertext.Length, tag.Length);
18 
19     return ret;
20 }
 1 public static string Decrypt(byte[] key, byte[] content)
 2 {
 3     var aes = new System.Security.Cryptography.AesGcm(key);
 4 
 5     var nonce = new byte[12];
 6     var ciphertext = new byte[content.Length - 12 - 16];
 7     var tag = new byte[16];
 8 
 9     Buffer.BlockCopy(content, 0, nonce, 0, 12);
10     Buffer.BlockCopy(content, 12, ciphertext, 0, ciphertext.Length);
11     Buffer.BlockCopy(content, content.Length - 16, tag, 0, 16);
12 
13     var plainttext = new byte[ciphertext.Length];
14     aes.Decrypt(nonce, ciphertext, tag, plainttext);
15 
16     return System.Text.Encoding.UTF8.GetString(plainttext);
17 }

以上就是AesGcm的使用方式。

posted on 2021-04-11 21:12  博兔  阅读(200)  评论(0编辑  收藏  举报