Reputation: 8618
I'm trying to serialise and encrypt simple dto's as a means to securely hand them around as strings.
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.
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.
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:
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.
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.
Upvotes: 1
Views: 2710
Reputation: 8618
There we go, thanks to @dbc ... how I didn't spot that I don't know!
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));
}
}
}
Upvotes: 1