-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathHardcodedSymmetricEncryptionKey.cs
More file actions
116 lines (95 loc) · 4.31 KB
/
HardcodedSymmetricEncryptionKey.cs
File metadata and controls
116 lines (95 loc) · 4.31 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
namespace HardcodedSymmetricEncryptionKey
{
class Program
{
static void Main(string[] args)
{
var a = new AesCryptoServiceProvider();
// BAD: explicit key assignment, hard-coded value
a.Key = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 };
var b = new AesCryptoServiceProvider()
{
// BAD: explicit key assignment, hard-coded value
Key = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }
};
var c = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 };
var d = c;
var byteArrayFromString = Encoding.UTF8.GetBytes("Hello, world: here is a very bad way to create a key");
// BAD: key assignment via variable, from hard-coded value
a.Key = d;
// GOOD (not really, but better than hard coding)
a.Key = File.ReadAllBytes("secret.key");
var cp = CreateProvider(d);
var iv = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 };
// BAD: hard-coded key passed to Encrypt [NOT DETECTED]
var ct = Encrypt("Test string here", c, iv);
// BAD: hard-coded key converted from string and passed to Encrypt [NOT DETECTED]
var ct1 = Encrypt("Test string here", byteArrayFromString, iv);
// GOOD (this function hashes password)
var de = DecryptWithPassword(ct, c, iv);
// BAD [NOT DETECTED]
CreateCryptographicKey(null, byteArrayFromString);
// GOOD
CreateCryptographicKey(null, File.ReadAllBytes("secret.key"));
}
public static string DecryptWithPassword(byte[] cipherText, byte[] password, byte[] IV)
{
byte[] rawPlaintext;
var salt = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 };
using (Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(password, salt, 100))
{
using (Aes aes = new AesManaged())
{
using (MemoryStream ms = new MemoryStream())
{
// GOOD: for this test, the flow through Rfc2898DeriveBytes should be considered GOOD.
// GOOD: Use of hard-coded password for Rfc2898DeriveBytes is found by Semmle CWE-798: HardcodedCredentials.ql
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(k1.GetBytes(16), IV), CryptoStreamMode.Write))
{
cs.Write(cipherText, 0, cipherText.Length);
}
rawPlaintext = ms.ToArray();
}
return Encoding.Unicode.GetString(rawPlaintext);
}
}
}
static SymmetricAlgorithm CreateProvider(byte[] key)
{
return new AesManaged()
{
// BAD: assignment from parameter
Key = key
};
}
public static byte[] Encrypt(string plaintext, byte[] key, byte[] IV)
{
byte[] rawPlaintext = Encoding.Unicode.GetBytes("Test string here");
byte[] cipherText = null;
using (Aes aes = new AesManaged())
{
using (MemoryStream ms = new MemoryStream())
{
// BAD: flow of hardcoded key to CreateEncryptor constructor
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(key, IV), CryptoStreamMode.Write))
{
cs.Write(rawPlaintext, 0, rawPlaintext.Length);
}
cipherText = ms.ToArray();
}
return cipherText;
}
}
static CryptographicKey CreateCryptographicKey(SymmetricKeyAlgorithmProvider p, byte[] bytes)
{
var buffer = CryptographicBuffer.CreateFromByteArray(bytes);
return p.CreateSymmetricKey(buffer);
}
}
}