#define TRACE using System; using System.Diagnostics; using System.Globalization; using System.IO; using System.Security.Cryptography; using System.Text; using ArchestrAServices.Common; namespace ArchestrAServices.Contract; internal static class AuthenticationCryptography { public static byte[] DeriveKey(byte[] passPhrase, byte[] saltValue, string hashAlgorithm, int passwordIterations, int keySize) { if (passPhrase == null || passPhrase.Length == 0) { throw new ArgumentNullException("passPhrase"); } if (saltValue == null || saltValue.Length == 0) { throw new ArgumentNullException("saltValue"); } if (string.IsNullOrEmpty(hashAlgorithm)) { throw new ArgumentNullException("hashAlgorithm"); } byte[] array = new byte[passPhrase.Length + saltValue.Length]; Buffer.BlockCopy(passPhrase, 0, array, 0, passPhrase.Length); Buffer.BlockCopy(saltValue, 0, array, passPhrase.Length, saltValue.Length); using MD5 mD = new MD5CryptoServiceProvider(); for (int i = 0; i < passwordIterations; i++) { array = mD.ComputeHash(array); } StringBuilder stringBuilder = new StringBuilder(); for (int j = 0; j < array.Length; j++) { stringBuilder.Append(array[j].ToString("x2")); } SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, string.Format(CultureInfo.CurrentCulture, "SvcAuth: DeriveKey generated '{0}' from '{1}'", new object[2] { stringBuilder.ToString(), passPhrase[0].ToString("x2") })); return Encoding.UTF8.GetBytes(stringBuilder.ToString()); } public static byte[] Encrypt(byte[] PlainPayload, byte[] passPhrase, byte[] saltValue, string hashAlgorithm, int passwordIterations, byte[] initVector, int keySize) { if (PlainPayload == null) { throw new ArgumentNullException("value"); } if (passPhrase == null || passPhrase.Length == 0) { throw new ArgumentNullException("passPhrase"); } if (saltValue == null || saltValue.Length == 0) { throw new ArgumentNullException("saltValue"); } if (string.IsNullOrEmpty(hashAlgorithm)) { throw new ArgumentNullException("hashAlgorithm"); } if (initVector == null || initVector.Length == 0) { throw new ArgumentNullException("initVector"); } byte[] rgbKey = DeriveKey(passPhrase, saltValue, hashAlgorithm, passwordIterations, 32); byte[] array = null; using RijndaelManaged rijndaelManaged = new RijndaelManaged(); rijndaelManaged.Mode = CipherMode.CBC; ICryptoTransform transform = rijndaelManaged.CreateEncryptor(rgbKey, initVector); using MemoryStream memoryStream = new MemoryStream(); using CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write); cryptoStream.Write(PlainPayload, 0, PlainPayload.Length); cryptoStream.FlushFinalBlock(); return memoryStream.ToArray(); } public static byte[] Decrypt(byte[] CypherPayload, byte[] passPhrase, byte[] saltValue, string hashAlgorithm, int passwordIterations, byte[] initVector, int keySize) { if (CypherPayload == null) { throw new ArgumentNullException("value"); } if (passPhrase == null || passPhrase.Length == 0) { throw new ArgumentNullException("passPhrase"); } if (saltValue == null || saltValue.Length == 0) { throw new ArgumentNullException("saltValue"); } if (string.IsNullOrEmpty(hashAlgorithm)) { throw new ArgumentNullException("hashAlgorithm"); } if (initVector == null || initVector.Length == 0) { throw new ArgumentNullException("initVector"); } byte[] rgbKey = DeriveKey(passPhrase, saltValue, hashAlgorithm, passwordIterations, 32); byte[] array = null; using (RijndaelManaged rijndaelManaged = new RijndaelManaged()) { rijndaelManaged.Mode = CipherMode.CBC; ICryptoTransform transform = rijndaelManaged.CreateDecryptor(rgbKey, initVector); using MemoryStream stream = new MemoryStream(CypherPayload); using CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Read); array = new byte[CypherPayload.Length]; int num = 0; try { num = cryptoStream.Read(array, 0, array.Length); } catch (Exception) { num = array.Length; for (int i = 0; i < num; i++) { array[i] = 0; } } } return array; } }