WingMan – Diff between revs 10 and 12

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 10 Rev 12
Line 1... Line 1...
1 using System; 1 using System;
2 using System.IO; 2 using System.IO;
-   3 using System.Linq;
3 using System.Security.Cryptography; 4 using System.Security.Cryptography;
4 using System.Text; 5 using System.Text;
-   6 using System.Threading.Tasks;
Line 5... Line 7...
5   7  
6 namespace WingMan.Utilities 8 namespace WingMan.Utilities
7 { 9 {
8 public static class AES 10 public static class AES
-   11 {
9 { 12 private const int AesKeyIterations = 4096;
10 private const int AesBlockSize = 128; 13 private const int AesBlockSize = 128;
11 private const CipherMode AesCipherMode = CipherMode.CBC; 14 private const CipherMode AesCipherMode = CipherMode.CBC;
12 private const PaddingMode AesPaddingMode = PaddingMode.PKCS7; 15 private const PaddingMode AesPaddingMode = PaddingMode.PKCS7;
13 private const int AesKeySaltBytes = 16; 16 private const int AesKeySaltBytes = 16;
Line 21... Line 24...
21 /// </summary> 24 /// </summary>
22 /// <param name="data">the string to encrypt</param> 25 /// <param name="data">the string to encrypt</param>
23 /// <param name="key">the encryption key</param> 26 /// <param name="key">the encryption key</param>
24 /// <param name="separator">the separator to use between the cyphertext and the IV</param> 27 /// <param name="separator">the separator to use between the cyphertext and the IV</param>
25 /// <returns>Base64 encoded encrypted data</returns> 28 /// <returns>Base64 encoded encrypted data</returns>
26 public static byte[] Encrypt(byte[] data, string key, string separator = ":") 29 public static async Task<byte[]> Encrypt(byte[] data, string key, string separator = ":")
27 { 30 {
28 using (var rijdanelManaged = new RijndaelManaged()) 31 using (var rijdanelManaged = new RijndaelManaged())
29 { 32 {
30 // FIPS-197 / CBC 33 // FIPS-197 / CBC
31 rijdanelManaged.BlockSize = AesBlockSize; 34 rijdanelManaged.BlockSize = AesBlockSize;
Line 33... Line 36...
33 rijdanelManaged.Padding = AesPaddingMode; 36 rijdanelManaged.Padding = AesPaddingMode;
Line 34... Line 37...
34   37  
35 // Compute the salt and the IV from the key. 38 // Compute the salt and the IV from the key.
36 var salt = new byte[AesKeySaltBytes]; 39 var salt = new byte[AesKeySaltBytes];
37 Rng.GetBytes(salt); 40 Rng.GetBytes(salt);
38 using (var derivedKey = new Rfc2898DeriveBytes(key, salt)) -  
39 { 41 var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations);
40 rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8); 42 rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
Line 41... Line 43...
41 rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8); 43 rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
-   44  
-   45 using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV))
42   46 {
43 using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV)) 47 using (var memoryStream = new MemoryStream())
44 { 48 {
45 using (var memoryStream = new MemoryStream()) 49 using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
46 { 50 {
47 using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) -  
48 { -  
49 using (var inputStream = new MemoryStream(data)) 51 using (var inputStream = new MemoryStream(data))
50 { 52 {
51 inputStream.CopyTo(cryptoStream); -  
52 cryptoStream.FlushFinalBlock(); -  
Line 53... Line 53...
53   53 await inputStream.CopyToAsync(cryptoStream);
Line 54... Line 54...
54 inputStream.Position = 0L; 54 cryptoStream.FlushFinalBlock();
55   -  
56 var payload = memoryStream.ToArray(); -  
57   -  
58 var base64Salt = Convert.ToBase64String(salt); -  
59 var base64Payload = Convert.ToBase64String(payload); 55  
60   56 inputStream.Position = 0L;
61 return Encoding.UTF8.GetBytes($"{base64Salt}{separator}{base64Payload}"); 57  
62 } 58 return salt.Concat(memoryStream.ToArray()).ToArray();
63 } 59 }
Line 78... Line 74...
78 /// separator 74 /// separator
79 /// </param> 75 /// </param>
80 /// <param name="key">the encryption key</param> 76 /// <param name="key">the encryption key</param>
81 /// <param name="separator">the separator to use between the cyphertext and the IV</param> 77 /// <param name="separator">the separator to use between the cyphertext and the IV</param>
82 /// <returns>the decrypted data</returns> 78 /// <returns>the decrypted data</returns>
83 public static byte[] Decrypt(byte[] data, string key, string separator = ":") 79 public static async Task<byte[]> Decrypt(byte[] data, string key, string separator = ":")
84 { 80 {
85 var input = Encoding.UTF8.GetString(data); 81 var salt = data.Take(AesKeySaltBytes).ToArray();
86   -  
87 // retrieve the salt from the data. -  
88 var segments = input.Split(new[] {separator}, StringSplitOptions.None); 82 var text = data.Skip(AesKeySaltBytes).ToArray();
89 if (segments.Length != 2) -  
90 throw new ArgumentException("Invalid data: " + input); -  
Line 91... Line 83...
91   83  
92 using (var rijdanelManaged = new RijndaelManaged()) 84 using (var rijdanelManaged = new RijndaelManaged())
93 { 85 {
94 // FIPS-197 / CBC 86 // FIPS-197 / CBC
95 rijdanelManaged.BlockSize = AesBlockSize; 87 rijdanelManaged.BlockSize = AesBlockSize;
96 rijdanelManaged.Mode = AesCipherMode; 88 rijdanelManaged.Mode = AesCipherMode;
Line 97... Line 89...
97 rijdanelManaged.Padding = AesPaddingMode; 89 rijdanelManaged.Padding = AesPaddingMode;
98   90  
99 // Retrieve the key and the IV from the salt. -  
100 using (var derivedKey = new Rfc2898DeriveBytes(key, Convert.FromBase64String(segments[0].Trim()))) 91 // Retrieve the key and the IV from the salt.
101 { 92 var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations);
Line 102... Line 93...
102 rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8); 93 rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
-   94 rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
-   95  
103 rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8); 96 using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV))
104   97 {
105 using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV)) 98 using (var memoryStream = new MemoryStream(text))
106 { 99 {
107 using (var memoryStream = new MemoryStream(Convert.FromBase64String(segments[1].Trim()))) 100 using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
108 { 101 {
-   102 using (var outputStream = new MemoryStream())
109 using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) 103 {
-   104 await cryptoStream.CopyToAsync(outputStream);
110 { 105  
111 using (var streamReader = new StreamReader(cryptoStream)) -  
112 { 106 outputStream.Position = 0L;
113 return Encoding.UTF8.GetBytes(streamReader.ReadToEnd()); 107  
114 } 108 return outputStream.ToArray();
115 } 109 }
116 } 110 }