我正在使用BountyCastle.NetCore NuGet库从我们的服务器解密已经准备好的加密消息。我能够成功使用Java密码库(本机)和Python(pycrptodome)实现。通常,我们的服务器正在按照以下方式准备消息:
解密策略是:
通过base64解码来准备AES-256密钥 cryptographyKey。
通过base64解码消息正文来准备密文字节。
应用基于this example的通用算法,我的实现如下所示:
注意:我没有在下面的代码中应用代码,因为这更多是验证步骤,而且我无法解密邮件。
public string Decrypt(string cryptoKey, string cypherText)
{
string sR = string.Empty;
try
{
// Prepare the AES-256 secret key by decoding the cryptographyKey
var keyBytes = Convert.FromBase64String(cryptoKey);
// Prepare the Cypher bytes by decoding the cypher text
var cypherBytes = Convert.FromBase64String(cypherText);
// <------AAD----->
// [---][--NONCE--][-----Encrypted Message-----][---TAG---]
// <-------------------CypherText------------------------->
// Prepare the AAD - first AAD_LENGTH from cypher
var aad = new Byte[AAD_LENGTH];
Array.Copy(cypherBytes, 0, aad, 0, AAD_LENGTH);
// Prepare NONCE - bytes 4-16 from AAD
var nonce = new Byte[NONCE_LENGTH];
Array.Copy(aad, AAD_LENGTH - NONCE_LENGTH, nonce, 0, NONCE_LENGTH);
// Extract the encrypted message within the body - between AAD and TAG section
var encryptedMsgSize = cypherBytes.Length - TAG_LENGTH - AAD_LENGTH;
var encryptedMsg = new Byte[encryptedMsgSize];
Array.Copy(cypherBytes, AAD_LENGTH, encryptedMsg, 0, encryptedMsgSize);
GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine());
AeadParameters parameters = new AeadParameters(new KeyParameter(keyBytes), 128, nonce);
cipher.Init(false, parameters);
cipher.ProcessAadBytes(cypherBytes, 0, AAD_LENGTH);
byte[] plainBytes = new byte[cipher.GetOutputSize(encryptedMsg.Length)];
Int32 retLen = cipher.ProcessBytes(encryptedMsg, 0, encryptedMsg.Length, plainBytes, 0);
cipher.DoFinal(plainBytes, retLen);
sR = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n\0".ToCharArray());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
return sR;
}
尽管尝试许多不同的组合,设置不同的参数等,但它总是在行上引发异常:
cipher.DoFinal(plainBytes, retLen);
“在GCM中进行Mac检查失败”。
任何其他建议都将受到欢迎:-)