Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Rfc2898DeriveBytes.cs
Go to the documentation of this file.
4using System.Text;
6
8
9[UnsupportedOSPlatform("browser")]
11{
12 private byte[] _salt;
13
14 private uint _iterations;
15
16 private HMAC _hmac;
17
18 private readonly int _blockSize;
19
20 private byte[] _buffer;
21
22 private uint _block;
23
24 private int _startIndex;
25
26 private int _endIndex;
27
28 private static readonly Encoding s_throwingUtf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
29
31
32 public int IterationCount
33 {
34 get
35 {
36 return (int)_iterations;
37 }
38 set
39 {
40 if (value <= 0)
41 {
43 }
44 _iterations = (uint)value;
45 Initialize();
46 }
47 }
48
49 public byte[] Salt
50 {
51 get
52 {
53 return _salt.AsSpan(0, _salt.Length - 4).ToArray();
54 }
55 set
56 {
57 if (value == null)
58 {
59 throw new ArgumentNullException("value");
60 }
61 _salt = new byte[value.Length + 4];
62 value.AsSpan().CopyTo(_salt);
63 Initialize();
64 }
65 }
66
67 public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations)
68 : this(password, salt, iterations, HashAlgorithmName.SHA1)
69 {
70 }
71
72 public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
73 : this(password, salt, iterations, hashAlgorithm, clearPassword: false)
74 {
75 }
76
77 public Rfc2898DeriveBytes(string password, byte[] salt)
78 : this(password, salt, 1000)
79 {
80 }
81
82 public Rfc2898DeriveBytes(string password, byte[] salt, int iterations)
83 : this(password, salt, iterations, HashAlgorithmName.SHA1)
84 {
85 }
86
87 public Rfc2898DeriveBytes(string password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
88 : this(Encoding.UTF8.GetBytes(password), salt, iterations, hashAlgorithm, clearPassword: true)
89 {
90 }
91
92 public Rfc2898DeriveBytes(string password, int saltSize)
93 : this(password, saltSize, 1000)
94 {
95 }
96
97 public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
98 : this(password, saltSize, iterations, HashAlgorithmName.SHA1)
99 {
100 }
101
102 public Rfc2898DeriveBytes(string password, int saltSize, int iterations, HashAlgorithmName hashAlgorithm)
103 {
104 if (saltSize < 0)
105 {
107 }
108 if (iterations <= 0)
109 {
111 }
112 _salt = new byte[saltSize + 4];
113 RandomNumberGenerator.Fill(_salt.AsSpan(0, saltSize));
114 _iterations = (uint)iterations;
115 byte[] bytes = Encoding.UTF8.GetBytes(password);
116 HashAlgorithm = hashAlgorithm;
119 _blockSize = _hmac.HashSize >> 3;
120 Initialize();
121 }
122
123 internal Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, bool clearPassword)
124 {
125 if (salt == null)
126 {
127 throw new ArgumentNullException("salt");
128 }
129 if (iterations <= 0)
130 {
132 }
133 if (password == null)
134 {
135 throw new NullReferenceException();
136 }
137 _salt = new byte[salt.Length + 4];
138 salt.AsSpan().CopyTo(_salt);
139 _iterations = (uint)iterations;
140 HashAlgorithm = hashAlgorithm;
141 _hmac = OpenHmac(password);
142 if (clearPassword)
143 {
145 }
146 _blockSize = _hmac.HashSize >> 3;
147 Initialize();
148 }
149
150 protected override void Dispose(bool disposing)
151 {
152 if (disposing)
153 {
154 if (_hmac != null)
155 {
156 _hmac.Dispose();
157 _hmac = null;
158 }
159 if (_buffer != null)
160 {
162 }
163 if (_salt != null)
164 {
166 }
167 }
168 base.Dispose(disposing);
169 }
170
171 public override byte[] GetBytes(int cb)
172 {
173 if (cb <= 0)
174 {
176 }
177 byte[] array = new byte[cb];
178 int i = 0;
179 int num = _endIndex - _startIndex;
180 if (num > 0)
181 {
182 if (cb < num)
183 {
185 _startIndex += cb;
186 return array;
187 }
189 _startIndex = (_endIndex = 0);
190 i += num;
191 }
192 for (; i < cb; i += _blockSize)
193 {
194 Func();
195 int num2 = cb - i;
196 if (num2 >= _blockSize)
197 {
199 continue;
200 }
201 Buffer.BlockCopy(_buffer, 0, array, i, num2);
202 _startIndex = num2;
203 _endIndex = _buffer.Length;
204 return array;
205 }
206 return array;
207 }
208
209 [Obsolete("Rfc2898DeriveBytes.CryptDeriveKey is obsolete and is not supported. Use PasswordDeriveBytes.CryptDeriveKey instead.", DiagnosticId = "SYSLIB0033", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
210 public byte[] CryptDeriveKey(string algname, string alghashname, int keySize, byte[] rgbIV)
211 {
213 }
214
215 public override void Reset()
216 {
217 Initialize();
218 }
219
220 private HMAC OpenHmac(byte[] password)
221 {
222 HashAlgorithmName hashAlgorithm = HashAlgorithm;
223 if (string.IsNullOrEmpty(hashAlgorithm.Name))
224 {
226 }
227 if (hashAlgorithm == HashAlgorithmName.SHA1)
228 {
229 return new HMACSHA1(password);
230 }
231 if (hashAlgorithm == HashAlgorithmName.SHA256)
232 {
233 return new HMACSHA256(password);
234 }
235 if (hashAlgorithm == HashAlgorithmName.SHA384)
236 {
237 return new HMACSHA384(password);
238 }
239 if (hashAlgorithm == HashAlgorithmName.SHA512)
240 {
241 return new HMACSHA512(password);
242 }
244 }
245
246 [MemberNotNull("_buffer")]
247 private void Initialize()
248 {
249 if (_buffer != null)
250 {
252 }
253 _buffer = new byte[_blockSize];
254 _block = 0u;
255 _startIndex = (_endIndex = 0);
256 }
257
258 private void Func()
259 {
260 if (_block == uint.MaxValue)
261 {
263 }
264 BinaryPrimitives.WriteUInt32BigEndian(_salt.AsSpan(_salt.Length - 4), _block + 1);
265 Span<byte> span = stackalloc byte[64];
266 span = span.Slice(0, _blockSize);
267 if (!_hmac.TryComputeHash(_salt, span, out var bytesWritten) || bytesWritten != _blockSize)
268 {
269 throw new CryptographicException();
270 }
271 span.CopyTo(_buffer);
272 for (int i = 2; i <= _iterations; i++)
273 {
274 if (!_hmac.TryComputeHash(span, span, out bytesWritten) || bytesWritten != _blockSize)
275 {
276 throw new CryptographicException();
277 }
278 for (int num = _buffer.Length - 1; num >= 0; num--)
279 {
280 _buffer[num] ^= span[num];
281 }
282 }
283 _block++;
284 }
285
286 public static byte[] Pbkdf2(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
287 {
288 if (password == null)
289 {
290 throw new ArgumentNullException("password");
291 }
292 if (salt == null)
293 {
294 throw new ArgumentNullException("salt");
295 }
296 return Pbkdf2(new ReadOnlySpan<byte>(password), new ReadOnlySpan<byte>(salt), iterations, hashAlgorithm, outputLength);
297 }
298
299 public static byte[] Pbkdf2(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
300 {
301 if (iterations <= 0)
302 {
304 }
305 if (outputLength < 0)
306 {
308 }
309 ValidateHashAlgorithm(hashAlgorithm);
310 byte[] array = new byte[outputLength];
311 Pbkdf2Core(password, salt, array, iterations, hashAlgorithm);
312 return array;
313 }
314
315 public static void Pbkdf2(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, Span<byte> destination, int iterations, HashAlgorithmName hashAlgorithm)
316 {
317 if (iterations <= 0)
318 {
320 }
321 ValidateHashAlgorithm(hashAlgorithm);
322 Pbkdf2Core(password, salt, destination, iterations, hashAlgorithm);
323 }
324
325 public static byte[] Pbkdf2(string password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
326 {
327 if (password == null)
328 {
329 throw new ArgumentNullException("password");
330 }
331 if (salt == null)
332 {
333 throw new ArgumentNullException("salt");
334 }
335 return Pbkdf2(password.AsSpan(), new ReadOnlySpan<byte>(salt), iterations, hashAlgorithm, outputLength);
336 }
337
338 public static byte[] Pbkdf2(ReadOnlySpan<char> password, ReadOnlySpan<byte> salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
339 {
340 if (outputLength < 0)
341 {
343 }
344 if (iterations <= 0)
345 {
347 }
348 ValidateHashAlgorithm(hashAlgorithm);
349 byte[] array = new byte[outputLength];
350 Pbkdf2Core(password, salt, array, iterations, hashAlgorithm);
351 return array;
352 }
353
354 public static void Pbkdf2(ReadOnlySpan<char> password, ReadOnlySpan<byte> salt, Span<byte> destination, int iterations, HashAlgorithmName hashAlgorithm)
355 {
356 if (iterations <= 0)
357 {
359 }
360 ValidateHashAlgorithm(hashAlgorithm);
361 Pbkdf2Core(password, salt, destination, iterations, hashAlgorithm);
362 }
363
364 private static void Pbkdf2Core(ReadOnlySpan<char> password, ReadOnlySpan<byte> salt, Span<byte> destination, int iterations, HashAlgorithmName hashAlgorithm)
365 {
366 if (!destination.IsEmpty)
367 {
368 byte[] array = null;
369 int maxByteCount = s_throwingUtf8Encoding.GetMaxByteCount(password.Length);
370 Span<byte> span = ((maxByteCount <= 256) ? stackalloc byte[256] : ((Span<byte>)(array = System.Security.Cryptography.CryptoPool.Rent(maxByteCount))));
371 Span<byte> bytes = span;
372 Span<byte> span2 = bytes[..s_throwingUtf8Encoding.GetBytes(password, bytes)];
373 try
374 {
375 Pbkdf2Implementation.Fill(span2, salt, iterations, hashAlgorithm, destination);
376 }
377 finally
378 {
380 }
381 if (array != null)
382 {
384 }
385 }
386 }
387
388 private static void Pbkdf2Core(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, Span<byte> destination, int iterations, HashAlgorithmName hashAlgorithm)
389 {
390 if (!destination.IsEmpty)
391 {
392 Pbkdf2Implementation.Fill(password, salt, iterations, hashAlgorithm, destination);
393 }
394 }
395
396 private static void ValidateHashAlgorithm(HashAlgorithmName hashAlgorithm)
397 {
398 if (string.IsNullOrEmpty(hashAlgorithm.Name))
399 {
401 }
402 string name = hashAlgorithm.Name;
403 if (name != HashAlgorithmName.SHA1.Name && name != HashAlgorithmName.SHA256.Name && name != HashAlgorithmName.SHA384.Name && name != HashAlgorithmName.SHA512.Name)
404 {
406 }
407 }
408}
static void Fill(ReadOnlySpan< byte > password, ReadOnlySpan< byte > salt, int iterations, HashAlgorithmName hashAlgorithmName, Span< byte > destination)
static unsafe void Clear(Array array)
Definition Array.cs:755
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static void WriteUInt32BigEndian(Span< byte > destination, uint value)
static string ArgumentOutOfRange_NeedPosNum
Definition SR.cs:20
static string Cryptography_UnknownHashAlgorithm
Definition SR.cs:152
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string Cryptography_ExceedKdfExtractLimit
Definition SR.cs:174
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
static string Cryptography_HashAlgorithmNameNullOrEmpty
Definition SR.cs:60
Definition SR.cs:7
static void Return(byte[] array, int clearSize=-1)
Definition CryptoPool.cs:12
static byte[] Rent(int minimumLength)
Definition CryptoPool.cs:7
override void Dispose(bool disposing)
Definition HMAC.cs:67
bool TryComputeHash(ReadOnlySpan< byte > source, Span< byte > destination, out int bytesWritten)
static byte[] Pbkdf2(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
Rfc2898DeriveBytes(string password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
Rfc2898DeriveBytes(string password, int saltSize, int iterations)
Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations)
static void Pbkdf2Core(ReadOnlySpan< byte > password, ReadOnlySpan< byte > salt, Span< byte > destination, int iterations, HashAlgorithmName hashAlgorithm)
Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
static void Pbkdf2Core(ReadOnlySpan< char > password, ReadOnlySpan< byte > salt, Span< byte > destination, int iterations, HashAlgorithmName hashAlgorithm)
Rfc2898DeriveBytes(string password, int saltSize, int iterations, HashAlgorithmName hashAlgorithm)
static byte[] Pbkdf2(string password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm, bool clearPassword)
static byte[] Pbkdf2(ReadOnlySpan< byte > password, ReadOnlySpan< byte > salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
static void Pbkdf2(ReadOnlySpan< char > password, ReadOnlySpan< byte > salt, Span< byte > destination, int iterations, HashAlgorithmName hashAlgorithm)
byte[] CryptDeriveKey(string algname, string alghashname, int keySize, byte[] rgbIV)
Rfc2898DeriveBytes(string password, byte[] salt, int iterations)
static void Pbkdf2(ReadOnlySpan< byte > password, ReadOnlySpan< byte > salt, Span< byte > destination, int iterations, HashAlgorithmName hashAlgorithm)
static byte[] Pbkdf2(ReadOnlySpan< char > password, ReadOnlySpan< byte > salt, int iterations, HashAlgorithmName hashAlgorithm, int outputLength)
static void ValidateHashAlgorithm(HashAlgorithmName hashAlgorithm)
Rfc2898DeriveBytes(string password, int saltSize)
static Encoding UTF8
Definition Encoding.cs:526
void CopyTo(Span< T > destination)
Definition Span.cs:224
Span< T > Slice(int start)
Definition Span.cs:271