예제 #1
0
        /// <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;
        }
예제 #2
0
        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);
        }
예제 #3
0
        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");
                            }
                        }
                    }
            }
        }
예제 #4
0
        /// <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);
        }