简体   繁体   English

.Net中的AES + HMAC加密

[英]AES + HMAC Encryption in .Net

I'm trying to serialise and encrypt simple dto's as a means to securely hand them around as strings. 我正在尝试序列化和加密简单的dto作为一种安全地将它们作为字符串传递的方法。

It seems that most people point me at Encrypt and decrypt a string when asking about this. 似乎大多数人都会在加密时指出我在询问时解密字符串 @jbtule took the time to provide a really detailed answer with 2 possible solutions. @jbtule花时间用2种可能的解决方案提供了非常详细的答案。

I have taken a copy of the second example from his gist https://gist.github.com/jbtule/4336842#file-aesthenhmac-cs (the file named "AESThenHMAC.cs" and put that in to my project. 我从他的要点https://gist.github.com/jbtule/4336842#file-aesthenhmac-cs (名为“AESThenHMAC.cs”的文件)中获取了第二个例子的副本,并将其放入我的项目中。

I then thought it might be good practice to wrap up and quickly test this solution but I can't seem to get it working. 然后我认为结束并快速测试这个解决方案可能是一个好习惯,但我似乎无法让它工作。

Could someone explain what I am doing wrong here? 有人可以解释我在这里做错了吗?

Here's my wrapper round @jbtule's code: 这是我的包装轮@ 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));
        }
    }
}

And then a simple unit test to confirm this all works: 然后一个简单的单元测试来确认这一切都有效:

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);
}

For some reason the decryption method returns null because the check performed on line 261 of jbtule's gist compares the value 255 to 0. 由于某种原因,解密方法返回null,因为在jbtule的gist的第261行上执行的检查将值255与0进行比较。

This is a follow on from my attempts to talk to the .NET types directly (see AesEncryption doesn't appear to decrypt right? ), I just need a solution that consistently works at this point. 这是我尝试直接与.NET类型对话的后续内容(请参阅AesEncryption似乎没有正确解密? ),我只需要一个在这一点上始终有效的解决方案。

There we go, thanks to @dbc ... how I didn't spot that I don't know! 我们去了,感谢@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));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM