/// <summary> /// Open the certificate store /// </summary> private SecretKeyStorage() { string secretKey = ConfigurationManager.AppSettings["SecretKey"]; byte[] data = StringToByteArray(secretKey); if (null == secretKey || secretKey.Length % 2 == 1) { throw new Exception("No valid SecurEntity Secret Key found"); } // Create a hash SHA512Managed sha = new SHA512Managed(); sha.Initialize(); sha.TransformBlock(data, 0, data.Length, data, 0); SecretKey = sha.Hash; }
private byte[] GetSystemEntropy() { SHA512Managed h = new SHA512Managed(); byte[] pb4 = new byte[4]; byte[] pb8 = new byte[8]; GAction <byte[], bool> f = delegate(byte[] pbValue, bool bClearValue) { if (pbValue == null) { Debug.Assert(false); return; } if (pbValue.Length == 0) { return; } h.TransformBlock(pbValue, 0, pbValue.Length, pbValue, 0); if (bClearValue) { MemUtil.ZeroByteArray(pbValue); } }; Action <int> fI32 = delegate(int iValue) { MemUtil.Int32ToBytesEx(iValue, pb4, 0); f(pb4, false); }; Action <long> fI64 = delegate(long lValue) { MemUtil.Int64ToBytesEx(lValue, pb8, 0); f(pb8, false); }; Action <string> fStr = delegate(string strValue) { if (strValue == null) { Debug.Assert(false); return; } if (strValue.Length == 0) { return; } f(StrUtil.Utf8.GetBytes(strValue), false); }; fI32(Environment.TickCount); fI64(DateTime.UtcNow.ToBinary()); #if !KeePassLibSD && !NETSTANDARD2_0 // In try-catch for systems without GUI; // https://sourceforge.net/p/keepass/discussion/329221/thread/20335b73/ try { Point pt = Cursor.Position; fI32(pt.X); fI32(pt.Y); } catch (Exception) { Debug.Assert(NativeLib.IsUnix()); } #endif try { fI32((int)NativeLib.GetPlatformID()); #if KeePassUAP fStr(EnvironmentExt.OSVersion.VersionString); #else fStr(Environment.OSVersion.VersionString); #endif fI32(Environment.ProcessorCount); #if !KeePassUAP && !NETSTANDARD2_0 fStr(Environment.CommandLine); fI64(Environment.WorkingSet); #endif } catch (Exception) { Debug.Assert(false); } try { foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) { fStr(de.Key as string); fStr(de.Value as string); } } catch (Exception) { Debug.Assert(false); } try { #if KeePassUAP f(DiagnosticsExt.GetProcessEntropy(), true); #elif !KeePassLibSD && !NETSTANDARD2_0 using (Process p = Process.GetCurrentProcess()) { fI64(p.Handle.ToInt64()); fI32(p.HandleCount); fI32(p.Id); fI64(p.NonpagedSystemMemorySize64); fI64(p.PagedMemorySize64); fI64(p.PagedSystemMemorySize64); fI64(p.PeakPagedMemorySize64); fI64(p.PeakVirtualMemorySize64); fI64(p.PeakWorkingSet64); fI64(p.PrivateMemorySize64); fI64(p.StartTime.ToBinary()); fI64(p.VirtualMemorySize64); fI64(p.WorkingSet64); // Not supported in Mono 1.2.6: // fI32(p.SessionId); } #endif } catch (Exception) { Debug.Assert(NativeLib.IsUnix()); } try { CultureInfo ci = CultureInfo.CurrentCulture; if (ci != null) { fI32(ci.GetHashCode()); } else { Debug.Assert(false); } } catch (Exception) { Debug.Assert(false); } f(Guid.NewGuid().ToByteArray(), false); f(GetCspRandom(), true); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); byte[] pbHash = h.Hash; h.Clear(); MemUtil.ZeroByteArray(pb4); MemUtil.ZeroByteArray(pb8); return(pbHash); }
static void Main(string[] args) { if (args == null || args.Length < 1 || (args[0].ToLower() != "e" && args[0].ToLower() != "d")) { Console.Error.WriteLine("Usage:"); Console.Error.WriteLine(" To encrypt: AesCrypt.exe e <file path>"); Console.Error.WriteLine(" To decrypt: AesCrypt.exe d <file path> <iv> <key>"); return; } if (args[0].ToLower() == "e") { // ENCRYPTION if (args.Length < 2) { Console.Error.WriteLine("Usage: AesCrypt.exe e <file path>"); } string fileToEncrypt = args[1]; FileInfo inpFile = new FileInfo(fileToEncrypt); if (!inpFile.Exists) { Console.Error.WriteLine("File does not exist"); return; } byte[] fileName = Encoding.UTF8.GetBytes(inpFile.FullName); string rootDir = Path.GetDirectoryName(fileToEncrypt); string randomName = Guid.NewGuid().ToString("N"); string tempName = Path.Combine(rootDir, randomName); string finalHash; if (File.Exists(tempName)) { Console.Error.WriteLine("ERROR: temporary file exists, wtf how does that even happen"); return; } using (FileStream inp = File.Open(fileToEncrypt, FileMode.Open, FileAccess.Read, FileShare.Read)) using (FileStream oup = File.Create(tempName)) using (AesManaged enc = new AesManaged()) { enc.KeySize = 256; enc.Mode = CipherMode.CBC; enc.GenerateIV(); enc.GenerateKey(); SHA512Managed originalHash = new SHA512Managed(); originalHash.Initialize(); SHA512Managed cryptedHash = new SHA512Managed(); using (CryptoStream hashStream = new CryptoStream(oup, cryptedHash, CryptoStreamMode.Write)) using (CryptoStream cs = new CryptoStream(hashStream, enc.CreateEncryptor(), CryptoStreamMode.Write)) { // crypted file structure: {name length x2}{full file name}{data length x8}{data}{sha512 hash of data x64} byte[] lenFileName = BitConverter.GetBytes((ushort)fileName.Length); cs.Write(lenFileName, 0, lenFileName.Length); cs.Write(fileName, 0, fileName.Length); byte[] fileSizeBits = BitConverter.GetBytes(inpFile.Length); cs.Write(fileSizeBits, 0, fileSizeBits.Length); byte[] data = new byte[64 * 1024]; int bytesRead; long bytesHashed = 0; do { // pull data from original file bytesRead = inp.Read(data, 0, data.Length); // send it to crypted stream cs.Write(data, 0, bytesRead); // also hash it for decryption verification purposes bytesHashed += originalHash.TransformBlock(data, 0, bytesRead, data, 0); } while (bytesRead > 0); // write original hash into crypted file so we can verify it after decryption originalHash.TransformFinalBlock(data, 0, 0); cs.Write(originalHash.Hash, 0, originalHash.Hash.Length); } finalHash = Base32.ToBase32String(cryptedHash.Hash); string iv = Convert.ToBase64String(enc.IV); string key = Convert.ToBase64String(enc.Key); Console.Out.WriteLine("{0} {1} {2}", finalHash, iv, key); } File.Move(tempName, Path.Combine(rootDir, finalHash)); } else { // DECRYPTION if (args.Length < 4) { Console.Error.WriteLine("Usage: AesCrypt.exe d <file path> <iv> <key>"); return; } FileInfo encFile = new FileInfo(args[1]); if (!encFile.Exists) { Console.Error.WriteLine("File does not exist"); return; } byte[] iv = Convert.FromBase64String(args[2]); if (iv == null || iv.Length < 1) { Console.Error.WriteLine("ERROR: invalid iv"); return; } byte[] key = Convert.FromBase64String(args[3]); if (key == null || key.Length < 1) { Console.Error.WriteLine("ERROR: invalid key"); return; } using (FileStream inp = encFile.OpenRead()) using (AesManaged aes = new AesManaged()) { aes.KeySize = 256; aes.Mode = CipherMode.CBC; aes.IV = iv; aes.Key = key; using (CryptoStream cs = new CryptoStream(inp, aes.CreateDecryptor(), CryptoStreamMode.Read)) { // crypted file structure: {name length x4}{full file name}{data length x8}{data}{sha512 hash of data x64} byte[] nameLengthBits = new byte[2]; if (cs.Read(nameLengthBits, 0, 2) != 2) { Console.Error.WriteLine("ERROR: Failed reading file name size"); return; } ushort nameLength = BitConverter.ToUInt16(nameLengthBits, 0); byte[] originalName = new byte[nameLength]; if (cs.Read(originalName, 0, nameLength) != nameLength) { Console.Error.WriteLine("ERROR: Failed reading file name"); return; } string fileName = Encoding.UTF8.GetString(originalName); byte[] dataLengthBits = new byte[8]; if (cs.Read(dataLengthBits, 0, dataLengthBits.Length) != dataLengthBits.Length) { Console.Error.WriteLine("ERROR: Failed reading data length"); return; } long dataLength = BitConverter.ToInt64(dataLengthBits, 0); string outputFileName = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileName(fileName)); if (File.Exists(outputFileName)) { Console.Error.WriteLine("ERROR: '{0}' already exists, exiting", outputFileName); return; } Console.Out.WriteLine("Decrypting what was originally called '{0}' ({1:N0} bytes)", fileName, dataLength); byte[] decryptedHash; long totalRead = 0; using (FileStream outputStream = new FileStream(outputFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read)) using (SHA512Managed hasher = new SHA512Managed()) { byte[] buffer = new byte[ReadBufferSize]; long bytesRemaining = dataLength; while (bytesRemaining > 0) { int readingThisRound = ReadBufferSize < bytesRemaining ? ReadBufferSize : (int)bytesRemaining; int bytesRead = cs.Read(buffer, 0, readingThisRound); totalRead += bytesRead; // dump decrypted data to file outputStream.Write(buffer, 0, bytesRead); // run it through the grinder for verification later int hashProgress = hasher.TransformBlock(buffer, 0, bytesRead, buffer, 0); Debug.Assert(hashProgress == bytesRead, "Hash calculation out of whack with file IO, wtf is going on"); bytesRemaining -= bytesRead; } hasher.TransformFinalBlock(buffer, 0, 0); decryptedHash = hasher.Hash; } byte[] originalHashBits = new byte[64]; if (cs.Read(originalHashBits, 0, originalHashBits.Length) != originalHashBits.Length) { Console.Error.WriteLine("ERROR: Failed reading verification hash, encrypted file is corrupted!"); return; } if (originalHashBits.SequenceEqual(decryptedHash)) { Console.Out.WriteLine("Successfully decrypted '{0}'", outputFileName); } else { Console.Out.WriteLine("Decryption FAIL"); } } } } }
/// <summary> /// Duplicates Python hashlib's pbkdf2_hmac for hash_name = 'sha512' and dklen = None /// /// Performance can be improved by precomputing _trans_36 and _trans_5c. /// Unlike Python's hash functions, .NET doesn't currently support copying state between blocks. /// This results in having to recompute hash of innerSeed and outerSeed on each iteration. /// </summary> /// <param name="password"></param> /// <param name="salt"></param> /// <param name="iterations"></param> /// <returns></returns> public static KzUInt512 pbkdf2_hmac_sha512(ReadOnlySpan <byte> password, ReadOnlySpan <byte> salt, int iterations) { if (iterations < 1) { throw new ArgumentException(); } var _password = password.ToArray(); using var inner = new SHA512Managed(); using var outer = new SHA512Managed(); var blocksize = 128; // match python hashlib's sha512 blocksize. if (_password.Length > blocksize) { inner.TransformFinalBlock(_password, 0, _password.Length); _password = inner.Hash; //inner.Initialize(); } if (_password.Length < blocksize) { Array.Resize(ref _password, blocksize); } var _trans_36 = new byte[256]; var _trans_5c = new byte[256]; for (var i = 0; i < 256; i++) { _trans_36[i] = (byte)(i ^ 0x36); _trans_5c[i] = (byte)(i ^ 0x5c); } var innerSeed = _password.Select(pb => _trans_36[pb]).ToArray(); var outerSeed = _password.Select(pb => _trans_5c[pb]).ToArray(); var hash = new KzUInt512(); var xhash = new KzUInt512(); var data = new byte[salt.Length + 4]; salt.CopyTo(data); var loop = 1; loop.AsReadOnlySpan(bigEndian: true).CopyTo(data.AsSpan(salt.Length)); var dataSpan = data.AsSpan(); for (var i = 0; i < iterations; i++) { inner.TransformBlock(innerSeed); outer.TransformBlock(outerSeed); inner.TransformFinalBlock(dataSpan, hash.Span); outer.TransformFinalBlock(hash.Span, hash.Span); dataSpan = hash.Span; xhash = i == 0 ? hash : xhash ^ hash; } return(xhash); }
public static ServiceManifestType SetHashVersion(this ServiceManifestType srv, string baseDir, string targetDir, int maxHashLength) { SHA512Managed sha; List <byte> configHash = new List <byte>(); int offset = 0; if (srv.CodePackage != null) { foreach (var cv in srv.CodePackage) { sha = new SHA512Managed(); offset = 0; var path = cv.Name == "Code" ? targetDir : Path.Combine(baseDir, "PackageRoot", cv.Name); foreach (var f in Directory.GetFiles(path, "*.dll").Concat(Directory.GetFiles(path, "*.exe"))) { var b = File.ReadAllBytes(f); sha.TransformBlock(b, offset, b.Length, b, offset); } sha.TransformFinalBlock(new byte[0], offset, 0); cv.Version += "." + Uri.EscapeDataString(Convert.ToBase64String(sha.Hash)); configHash.AddRange(sha.Hash); } } if (srv.ConfigPackage != null) { foreach (var cv in srv.ConfigPackage) { sha = new SHA512Managed(); offset = 0; foreach (var f in Directory.GetFiles(Path.Combine(baseDir, "PackageRoot", cv.Name))) { var b = File.ReadAllBytes(f); sha.TransformBlock(b, offset, b.Length, b, offset); } sha.TransformFinalBlock(new byte[0], offset, 0); cv.Version += "." + Uri.EscapeDataString(Convert.ToBase64String(sha.Hash)); configHash.AddRange(sha.Hash); } } if (srv.DataPackage != null) { foreach (var cv in srv.DataPackage) { sha = new SHA512Managed(); offset = 0; foreach (var f in Directory.GetFiles(Path.Combine(baseDir, "PackageRoot", cv.Name))) { var b = File.ReadAllBytes(f); sha.TransformBlock(b, offset, b.Length, b, offset); } sha.TransformFinalBlock(new byte[0], offset, 0); cv.Version += "." + Uri.EscapeDataString(Convert.ToBase64String(sha.Hash)); configHash.AddRange(sha.Hash); } } srv.Version += "." + Uri.EscapeDataString(Convert.ToBase64String(new SHA512Managed().ComputeHash(configHash.ToArray()))); return(srv); }