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的使用方式。