-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathFieldEncryptionDecryption.cs
91 lines (72 loc) · 2.95 KB
/
FieldEncryptionDecryption.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
using System;
using System.ComponentModel;
using System.IO;
using System.Security.Cryptography;
namespace CryptoShredding.Serialization.JsonConverters;
public class FieldEncryptionDecryption
{
private const string EncryptionPrefix = "crypto.";
public object GetEncryptedOrDefault(object value, ICryptoTransform encryptor)
{
if (encryptor is null)
throw new ArgumentNullException(nameof(encryptor));
var isEncryptionNeeded = value != null;
if (!isEncryptionNeeded) return default;
using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
using var writer = new StreamWriter(cryptoStream);
var valueAsText = value.ToString();
writer.Write(valueAsText);
writer.Flush();
cryptoStream.FlushFinalBlock();
var encryptedData = memoryStream.ToArray();
var encryptedText = Convert.ToBase64String(encryptedData);
var result = $"{EncryptionPrefix}{encryptedText}";
return result;
}
public object GetDecryptedOrDefault(object value, ICryptoTransform decryptor, Type destinationType)
{
if (value is null)
throw new ArgumentNullException(nameof(value));
var isText = value is string;
if (!isText) return value;
var valueAsText = (string)value;
var isEncrypted = valueAsText.StartsWith(EncryptionPrefix);
if (!isEncrypted)
{
var valueParsed = Parse(destinationType, valueAsText);
return valueParsed;
}
var isDecryptorAvailable = decryptor != null;
if (!isDecryptorAvailable)
{
var maskedValue = GetMaskedValue(destinationType);
return maskedValue;
}
var startIndex = EncryptionPrefix.Length;
var valueWithoutPrefix = valueAsText.Substring(startIndex);
var encryptedValue = Convert.FromBase64String(valueWithoutPrefix);
using var memoryStream = new MemoryStream(encryptedValue);
using var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
using var reader = new StreamReader(cryptoStream);
var decryptedText = reader.ReadToEnd();
var result = Parse(destinationType, decryptedText);
return result;
}
private object Parse(Type outputType, string valueAsString)
{
var converter = TypeDescriptor.GetConverter(outputType);
var result = converter.ConvertFromString(valueAsString);
return result;
}
private object GetMaskedValue(Type destinationType)
{
if (destinationType == typeof(string))
{
const string templateText = "***";
return templateText;
}
var defaultValue = Activator.CreateInstance(destinationType);
return defaultValue;
}
}