-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSymmetricEncryption.cs
101 lines (85 loc) · 3.83 KB
/
SymmetricEncryption.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
namespace EncryptionDecryption
{
/// <summary>
/// Provides symmetric encryption and decryption services
///
/// Original source: https://goo.gl/arhInA
/// </summary>
public class SymmetricEncryption
{
private readonly IBuffer randomBuffer;
private readonly IBuffer randomBufferCBC;
private readonly CryptographicKey cryptographicKey;
private readonly string algorithmName;
private readonly SymmetricKeyAlgorithmProvider cryptingProvider;
/// <summary>
/// Instantiate with a random generated buffer (not an option if
/// you want to persist the encryption to disk)
/// </summary>
public SymmetricEncryption()
{
algorithmName = SymmetricAlgorithmNames.AesEcbPkcs7;
cryptingProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
randomBuffer = CryptographicBuffer.GenerateRandom(cryptingProvider.BlockLength);
randomBufferCBC = null;
cryptographicKey = cryptingProvider.CreateSymmetricKey(randomBuffer);
}
/// <summary>
/// Instantiate with a custom generated buffer (good for
/// persisting the encryption to disk)
/// </summary>
/// <param name="randomBuffer">The custom generated buffer</param>
public SymmetricEncryption(IBuffer randomBuffer)
: this()
{
this.randomBuffer = randomBuffer;
cryptographicKey = cryptingProvider.CreateSymmetricKey(randomBuffer);
}
/// <summary>
/// Instantiate with a custom generated buffer (good for
/// persisting the encryption to disk) and with a custom
/// generated CBC buffer (is using CBC algorithms)
/// </summary>
/// <param name="randomBuffer">The custom generated buffer</param>
/// <param name="randomBufferCBC">The custom generated CBC buffer</param>
public SymmetricEncryption(IBuffer randomBuffer, IBuffer randomBufferCBC)
: this(randomBuffer)
{
this.randomBufferCBC = randomBufferCBC;
}
private bool IsMultipleOfBlockLength(IBuffer binaryData)
{
return (binaryData.Length % cryptingProvider.BlockLength) != 0;
}
/// <summary>
/// Encrypts a given string
/// </summary>
/// <param name="data">Data to be encrypted</param>
/// <returns>An encrypted string in Unicode</returns>
public string Encrypt(string data)
{
var binaryData = Encoding.Unicode.GetBytes(data).AsBuffer();
if (!algorithmName.Contains("PKCS7") && IsMultipleOfBlockLength(binaryData))
throw new Exception("Message buffer length must be multiple of block length !!");
var encryptedBinaryData = CryptographicEngine.Encrypt(cryptographicKey, binaryData, randomBufferCBC);
return Encoding.Unicode.GetString(encryptedBinaryData.ToArray());
}
/// <summary>
/// Decrypts a string in Unicode
/// </summary>
/// <param name="encryptedData">An encrypted string in Unicode</param>
/// <returns>The decrypted string in Unicode</returns>
public string Decrypt(string encryptedData)
{
var encryptedBinaryData = Encoding.Unicode.GetBytes(encryptedData).AsBuffer();
var decryptedData = CryptographicEngine.Decrypt(cryptographicKey, encryptedBinaryData, randomBufferCBC);
return Encoding.Unicode.GetString(decryptedData.ToArray());
}
}
}