AES/GCM(AES-128-GCM)身份验证标记在C#和Ruby中有所不同

本文关键字:Ruby 有所不同 GCM AES-128-GCM 身份验证 AES | 更新日期: 2023-09-27 18:23:41

我正在尝试用C#生成一个身份验证标记,我已经用Ruby生成了这个标记(用于测试目的)。然而,结果是不同的,但就我所见,投入是相等的。

在Ruby 2.0中使用OpenSSL 1.0.1c(Ubuntu 13.04):

require 'openssl'
require 'base64'
iv = Base64.decode64('kEWio77T7qWdytrIbUmRxA==')
key = Base64.decode64('FnUoIZvBUzC1Q/rn5WMi7Q==')
aad = Base64.decode64('/tTP07sPkoX8gah60eH89w==')
cipher = OpenSSL::Cipher.new('aes-128-gcm').encrypt
cipher.iv = iv
cipher.key = key
cipher.auth_data = aad
cipher.final
tag = Base64.strict_encode64(cipher.auth_tag)

得到的(编码的)标签是ie74XTWtSLNad0BKdrhvmQ==

在C#中使用BouncyCastle(片段):

var iv = Convert.FromBase64String("kEWio77T7qWdytrIbUmRxA==");
var key = Convert.FromBase64String("FnUoIZvBUzC1Q/rn5WMi7Q==");
var aad = Convert.FromBase64String("/tTP07sPkoX8gah60eH89w==");
var cipher = new GcmBlockCipher(new AesFastEngine());
var parameters = new AeadParameters(new KeyParameter(passkey), 128, iv, aad);
cipher.Init(true, parameters);
var cipherText = new byte[cipher.GetOutputSize(0)];
cipher.DoFinal(cipherText, 0);
var tag = Convert.ToBase64String(cipher.GetMac());

C#中的结果标签是sawCcwM1T8sGl5y6VT0CHA==

我在这里做错了什么?提前感谢您的回复!

AES/GCM(AES-128-GCM)身份验证标记在C#和Ruby中有所不同

好的,我安装了ruby 2.0.0并进行了一些测试。

首先,要复制C#中的原始输出"ie74XTWtSLNad0BKdrhvmQ==",请将C#中的IV设置为"new byte[12]"。

之所以有效,是因为在ruby代码设置中,cipher.key会清除您设置的任何IV,因此有效IV是默认长度的默认全零(GCM为96位)。所以你应该把静脉注射放在钥匙后面。

如果我们将ruby代码更改为这样做,那么输出将更改为"d1tAJ6Js94tSuPNbds0EJw==";仍然不匹配。要在C#中重现此值,请将IV截断为12个字节,即"kEWio77T7qWdytrI",此时输出匹配。

由此,我推断openssl/EVP正在截断你给它的任何IV。这应该不是绝对必要的,因为GCM确实支持更长的IV,但在某种意义上,96位是"首选"长度;我不确定这项政策在哪里执行。