.Net 中的 AES + HMAC 加密
AES + HMAC Encryption in .Net
我正在尝试对简单的 dto 进行序列化和加密,以此作为将它们作为字符串安全传递的一种方式。
好像大多数人在问这个的时候都指着我Encrypt and decrypt a string。
@jbtule 花时间提供了一个非常详细的答案,其中包含 2 种可能的解决方案。
我从他的要点 https://gist.github.com/jbtule/4336842#file-aesthenhmac-cs 中复制了第二个示例(名为 "AESThenHMAC.cs" 的文件并将其放入我的项目中。
然后我认为结束并快速测试此解决方案可能是个好习惯,但我似乎无法让它工作。
谁能解释一下我做错了什么?
这是我对@jbtule 代码的封装:
using Newtonsoft.Json;
using System.Text;
namespace Core.Data
{
public class AesCrypto<T> : ICrypto<T>
{
public string Encrypt(T source, string salt)
{
var enc = Encoding.Unicode;
var rawData = JsonConvert.SerializeObject(source);
return enc.GetString(AESThenHMAC.SimpleEncryptWithPassword(enc.GetBytes(rawData), salt));
}
public T Decrypt(string source, string salt)
{
var enc = Encoding.Unicode;
var decryptedBytes = AESThenHMAC.SimpleDecryptWithPassword(enc.GetBytes(source), salt);
return JsonConvert.DeserializeObject<T>(enc.GetString(decryptedBytes));
}
}
}
然后进行简单的单元测试以确认一切正常:
public void TestAesCrypto()
{
var testInput = new EncryptableObject { Id = 123, Name = "Victim", When = DateTimeOffset.UtcNow };
var crypto = new AesCrypto<EncryptableObject>();
var saltBytes = new byte[32];
new Random().NextBytes(saltBytes);
var testSalt = Encoding.Unicode.GetString(saltBytes);
var magicString = crypto.Encrypt(testInput, testSalt);
var testOutput = crypto.Decrypt(magicString, testSalt);
Assert.AreEqual(testInput.Id, testOutput.Id);
Assert.AreEqual(testInput.Name, testOutput.Name);
Assert.AreEqual(testInput.When, testOutput.When);
}
出于某种原因,解密方法 returns 为空,因为在 jbtule 的要点的第 261 行执行的检查将值 255 与 0 进行了比较。
这是我尝试直接与 .NET 类型对话的后续(参见 ),我只需要一个在这一点上始终有效的解决方案。
我们开始了,感谢@dbc ...我怎么没发现我不知道的东西!
using Newtonsoft.Json;
using System;
using System.Text;
namespace Core.Data
{
public class AesCrypto<T> : ICrypto<T>
{
public string Encrypt(T source, string salt)
{
var e = Encoding.UTF8;
var rawData = e.GetBytes(JsonConvert.SerializeObject(source));
var cipherData = AESThenHMAC.SimpleEncryptWithPassword(rawData, salt);
return Convert.ToBase64String(cipherData);
}
public T Decrypt(string source, string salt)
{
var e = Encoding.UTF8;
var decryptedBytes = AESThenHMAC.SimpleDecryptWithPassword(Convert.FromBase64String(source), salt);
return JsonConvert.DeserializeObject<T>(e.GetString(decryptedBytes));
}
}
}
我正在尝试对简单的 dto 进行序列化和加密,以此作为将它们作为字符串安全传递的一种方式。
好像大多数人在问这个的时候都指着我Encrypt and decrypt a string。 @jbtule 花时间提供了一个非常详细的答案,其中包含 2 种可能的解决方案。
我从他的要点 https://gist.github.com/jbtule/4336842#file-aesthenhmac-cs 中复制了第二个示例(名为 "AESThenHMAC.cs" 的文件并将其放入我的项目中。
然后我认为结束并快速测试此解决方案可能是个好习惯,但我似乎无法让它工作。
谁能解释一下我做错了什么?
这是我对@jbtule 代码的封装:
using Newtonsoft.Json;
using System.Text;
namespace Core.Data
{
public class AesCrypto<T> : ICrypto<T>
{
public string Encrypt(T source, string salt)
{
var enc = Encoding.Unicode;
var rawData = JsonConvert.SerializeObject(source);
return enc.GetString(AESThenHMAC.SimpleEncryptWithPassword(enc.GetBytes(rawData), salt));
}
public T Decrypt(string source, string salt)
{
var enc = Encoding.Unicode;
var decryptedBytes = AESThenHMAC.SimpleDecryptWithPassword(enc.GetBytes(source), salt);
return JsonConvert.DeserializeObject<T>(enc.GetString(decryptedBytes));
}
}
}
然后进行简单的单元测试以确认一切正常:
public void TestAesCrypto()
{
var testInput = new EncryptableObject { Id = 123, Name = "Victim", When = DateTimeOffset.UtcNow };
var crypto = new AesCrypto<EncryptableObject>();
var saltBytes = new byte[32];
new Random().NextBytes(saltBytes);
var testSalt = Encoding.Unicode.GetString(saltBytes);
var magicString = crypto.Encrypt(testInput, testSalt);
var testOutput = crypto.Decrypt(magicString, testSalt);
Assert.AreEqual(testInput.Id, testOutput.Id);
Assert.AreEqual(testInput.Name, testOutput.Name);
Assert.AreEqual(testInput.When, testOutput.When);
}
出于某种原因,解密方法 returns 为空,因为在 jbtule 的要点的第 261 行执行的检查将值 255 与 0 进行了比较。
这是我尝试直接与 .NET 类型对话的后续(参见
我们开始了,感谢@dbc ...我怎么没发现我不知道的东西!
using Newtonsoft.Json;
using System;
using System.Text;
namespace Core.Data
{
public class AesCrypto<T> : ICrypto<T>
{
public string Encrypt(T source, string salt)
{
var e = Encoding.UTF8;
var rawData = e.GetBytes(JsonConvert.SerializeObject(source));
var cipherData = AESThenHMAC.SimpleEncryptWithPassword(rawData, salt);
return Convert.ToBase64String(cipherData);
}
public T Decrypt(string source, string salt)
{
var e = Encoding.UTF8;
var decryptedBytes = AESThenHMAC.SimpleDecryptWithPassword(Convert.FromBase64String(source), salt);
return JsonConvert.DeserializeObject<T>(e.GetString(decryptedBytes));
}
}
}