wasSharpNET – Blame information for rev 30

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. //
5 ///////////////////////////////////////////////////////////////////////////
6  
7 using System;
8 using System.Collections.Generic;
9 using System.IO;
10 using System.Linq;
30 office 11 using System.Threading.Tasks;
1 office 12 using System.Security.Cryptography;
13  
14 namespace wasSharpNET.Cryptography
15 {
30 office 16 public static class AES
1 office 17 {
18 private const int AES_BLOCK_SIZE = 128;
19 private const CipherMode AES_CIPHER_MODE = CipherMode.CBC;
20 private const PaddingMode AES_PADDING_MODE = PaddingMode.PKCS7;
21 private const int AES_KEY_SALT_BYTES = 16;
3 office 22 private static readonly RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
1 office 23  
24 ///////////////////////////////////////////////////////////////////////////
25 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
26 ///////////////////////////////////////////////////////////////////////////
27 /// <summary>
28 /// Encrypts a string given a key and initialization vector.
29 /// </summary>
30 /// <param name="data">the string to encrypt</param>
31 /// <param name="key">the encryption key</param>
32 /// <param name="separator">the separator to use between the cyphertext and the IV</param>
33 /// <returns>Base64 encoded encrypted data</returns>
30 office 34 public static async Task<string> Encrypt(string data, string key, string separator = ":")
1 office 35 {
36 using (var rijdanelManaged = new RijndaelManaged())
37 {
38 // FIPS-197 / CBC
39 rijdanelManaged.BlockSize = AES_BLOCK_SIZE;
40 rijdanelManaged.Mode = AES_CIPHER_MODE;
41 rijdanelManaged.Padding = AES_PADDING_MODE;
42  
43 // Compute the salt and the IV from the key.
44 var salt = new byte[AES_KEY_SALT_BYTES];
45 rng.GetBytes(salt);
46 var derivedKey = new Rfc2898DeriveBytes(key, salt);
11 office 47 rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
48 rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
1 office 49  
50 using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV))
51 {
52 using (var memoryStream = new MemoryStream())
53 {
54 using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
55 {
56 using (var streamWriter = new StreamWriter(cryptoStream))
57 {
30 office 58 await streamWriter.WriteAsync(data);
59 return string.Join(separator, Convert.ToBase64String(salt), Convert.ToBase64String(memoryStream.ToArray()));
1 office 60 }
61 }
62 }
63 }
64 }
65 }
66  
67 ///////////////////////////////////////////////////////////////////////////
68 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
69 ///////////////////////////////////////////////////////////////////////////
70 /// <summary>
71 /// Decrypts a Base64 encoded string using AES with a given key and initialization vector.
72 /// </summary>
73 /// <param name="data">
74 /// a string consisting of the cyphertext to decrypt in Base64 and the IV in Base64 separated by the
75 /// separator
76 /// </param>
77 /// <param name="key">the encryption key</param>
78 /// <param name="separator">the separator to use between the cyphertext and the IV</param>
79 /// <returns>the decrypted data</returns>
30 office 80 public static async Task<string> Decrypt(string data, string key, string separator = ":")
1 office 81 {
82 // retrieve the salt from the data.
27 office 83 var segments = new List<string>(data.Split(new[] {separator}, StringSplitOptions.None));
29 office 84 if (!segments.Count().Equals(2))
1 office 85 throw new ArgumentException("Invalid data.");
86  
87 using (var rijdanelManaged = new RijndaelManaged())
88 {
89 // FIPS-197 / CBC
90 rijdanelManaged.BlockSize = AES_BLOCK_SIZE;
91 rijdanelManaged.Mode = AES_CIPHER_MODE;
92 rijdanelManaged.Padding = AES_PADDING_MODE;
93  
94 // Retrieve the key and the IV from the salt.
95 var derivedKey = new Rfc2898DeriveBytes(key, Convert.FromBase64String(segments.First().Trim()));
11 office 96 rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
97 rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
1 office 98  
99 using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV))
100 {
101 using (var memoryStream = new MemoryStream(Convert.FromBase64String(segments.Last().Trim())))
102 {
103 using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
104 {
105 using (var streamReader = new StreamReader(cryptoStream))
106 {
30 office 107 return await streamReader.ReadToEndAsync();
1 office 108 }
109 }
110 }
111 }
112 }
113 }
114 }
27 office 115 }