public void ComparisonTest(string password, string salt, int iterations, int bytes) { var _pass = System.Text.Encoding.UTF8.GetBytes(password); var _salt = System.Text.Encoding.UTF8.GetBytes(salt); var algo1 = new Rfc2898DeriveBytes(_pass, _salt, iterations); var algo2 = new Pbkdf2(new HMACSHA1(_pass), _salt, iterations); var h1 = algo1.GetBytes(bytes).ToHex(); var h2 = algo2.GetBytes(bytes).ToHex(); Assert.AreEqual(h1, h2); var h3 = algo1.GetBytes(bytes + 7).ToHex(); var h4 = algo2.GetBytes(bytes + 7).ToHex(); Assert.AreEqual(h3, h4); var h5 = algo1.GetBytes(1).ToHex(); var h6 = algo2.GetBytes(1).ToHex(); Assert.AreEqual(h5, h6); h5 = algo1.GetBytes(1).ToHex(); h6 = algo2.GetBytes(1).ToHex(); Assert.AreEqual(h5, h6); h5 = algo1.GetBytes(1).ToHex(); h6 = algo2.GetBytes(1).ToHex(); Assert.AreEqual(h5, h6); }
public void TestVector_PBKDF2_HMAC_SHA_256() { var p = System.Text.Encoding.ASCII.GetBytes("passwd"); var s = System.Text.Encoding.ASCII.GetBytes("salt"); var pbkdf = new Pbkdf2(new HMACSHA256(p), s, 1); var dk = pbkdf.GetBytes(64); var expected = Encoders.Hex.GetBytes(@" 55 ac 04 6e 56 e3 08 9f ec 16 91 c2 25 44 b6 05 f9 41 85 21 6d de 04 65 e6 8b 9d 57 c2 0d ac bc 49 ca 9c cc f1 79 b6 45 99 16 64 b3 9d 77 ef 31 7c 71 b8 45 b1 e3 0b d5 09 11 20 41 d3 a1 97 83" .Clean()); CollectionAssert.AreEqual(expected, dk); p = System.Text.Encoding.ASCII.GetBytes("Password"); s = System.Text.Encoding.ASCII.GetBytes("NaCl"); pbkdf = new Pbkdf2(new HMACSHA256(p), s, 80000); dk = pbkdf.GetBytes(64); expected = Encoders.Hex.GetBytes(@" 4d dc d8 f6 0b 98 be 21 83 0c ee 5e f2 27 01 f9 64 1a 44 18 d0 4c 04 14 ae ff 08 87 6b 34 ab 56 a1 d4 25 a1 22 58 33 54 9a db 84 1b 51 c9 b3 17 6a 27 2b de bb a1 d0 78 47 8f 62 b3 97 f3 3c 8d" .Clean()); CollectionAssert.AreEqual(expected, dk); }
public void Test_Pbkdf2() { byte[] password = new byte[256]; byte[] salt = new byte[256]; _random.NextBytes(password); _random.NextBytes(salt); using (var hmac = new System.Security.Cryptography.HMACSHA1()) { Pbkdf2 pbkdf2 = new Pbkdf2(hmac, password, salt, 1024); System.Security.Cryptography.Rfc2898DeriveBytes rfc2898DeriveBytes = new System.Security.Cryptography.Rfc2898DeriveBytes(password, salt, 1024); Assert.IsTrue(CollectionUtilities.Equals(pbkdf2.GetBytes(1024), rfc2898DeriveBytes.GetBytes(1024)), "Pbkdf2 #1"); } //_random.NextBytes(password); //_random.NextBytes(salt); //using (var hmac = new System.Security.Cryptography.HMACSHA256()) //{ // CryptoConfig.AddAlgorithm(typeof(SHA256Cng), // "SHA256", // "SHA256Cng", // "System.Security.Cryptography.SHA256", // "System.Security.Cryptography.SHA256Cng"); // hmac.HashName = "System.Security.Cryptography.SHA256"; // Pbkdf2 pbkdf2 = new Pbkdf2(hmac, password, salt, 1024); // var h = pbkdf2.GetBytes(10); //} }
byte[] PBKDF2(byte[] password, byte[] salt, int iterations, int outputBytes) { using (var hmac = new HMACSHA256()) { var df = new Pbkdf2(hmac, password, salt, iterations); var bytes = df.GetBytes(outputBytes); return(bytes); } }
public void DoPbkTest(string password, string salt, int iterations, int dkLen, string expected) { using (var hmac = new HMACSHA256()) { var mine = new Pbkdf2(hmac, System.Text.Encoding.UTF8.GetBytes(password), System.Text.Encoding.UTF8.GetBytes(salt), iterations); sbyte[] result = mine.GetBytes(dkLen); byte[] usResult = (byte[])(Array)result; String hex = BitConverter.ToString(usResult); Assert.AreEqual(hex, expected); } }
public string HashPassword(string password) { byte[] salt = new byte[32]; Random r = new Random(); r.NextBytes(salt); Pbkdf2 pbkdf2 = new Pbkdf2(new HMACSHA256(), System.Text.Encoding.UTF8.GetBytes(password), salt); return(Convert.ToBase64String(pbkdf2.GetBytes(32)) + ":" + Convert.ToBase64String(salt)); }
/// <summary> /// Generate authentication informations and store them in a serializable object to allow persistence /// </summary> /// <param name="email">email</param> /// <param name="password">password</param> /// <returns><see cref="AuthInfos" /> object containing encrypted data</returns> /// <exception cref="ArgumentNullException">email or password is null</exception> public AuthInfos GenerateAuthInfos(string email, string password) { if (string.IsNullOrEmpty(email)) { throw new ArgumentNullException("email"); } if (string.IsNullOrEmpty(password)) { throw new ArgumentNullException("password"); } // Prelogin to retrieve account version PreLoginRequest preLoginRequest = new PreLoginRequest(email); PreLoginResponse preLoginResponse = this.Request <PreLoginResponse>(preLoginRequest); if (preLoginResponse.Version == 2 && !string.IsNullOrEmpty(preLoginResponse.Salt)) { // Mega uses a new way to hash password based on a salt sent by Mega during prelogin var saltBytes = preLoginResponse.Salt.FromBase64(); var passwordBytes = password.ToBytesPassword(); const int Iterations = 100000; var derivedKeyBytes = new byte[32]; using (var hmac = new HMACSHA512()) { var pbkdf2 = new Pbkdf2(hmac, passwordBytes, saltBytes, Iterations); derivedKeyBytes = pbkdf2.GetBytes(derivedKeyBytes.Length); } // Derived key contains master key (0-16) and password hash (16-32) return(new AuthInfos( email, derivedKeyBytes.Skip(16).ToArray().ToBase64(), derivedKeyBytes.Take(16).ToArray())); } else if (preLoginResponse.Version == 1) { // Retrieve password as UTF8 byte array byte[] passwordBytes = password.ToBytesPassword(); // Encrypt password to use password as key for the hash byte[] passwordAesKey = PrepareKey(passwordBytes); // Hash email and password to decrypt master key on Mega servers string hash = GenerateHash(email.ToLowerInvariant(), passwordAesKey); return(new AuthInfos(email, hash, passwordAesKey)); } else { throw new NotSupportedException("Version of account not supported"); } }
public void Sha256_3() { using var hmac = new HMACSHA256(); var P = "password"; var S = "salt"; var c = 4096; var dkLen = 32; var DK = "c5 e4 78 d5 92 88 c8 41 aa 53 0d b6 84 5c 4c 8d 96 28 93 a0 01 ce 4e 11 a4 96 38 73 aa 98 13 4a"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha256_2() { using var hmac = new HMACSHA256(); var P = "password"; var S = "salt"; var c = 2; var dkLen = 32; var DK = "ae 4d 0c 95 af 6b 46 d3 2d 0a df f9 28 f0 6d d0 2a 30 3f 8e f3 c2 51 df d6 e2 d8 5a 95 47 4c 43"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha1_1() // RFC 6070 { using var hmac = new HMACSHA1(); var P = "password"; var S = "salt"; var c = 1; var dkLen = 20; var DK = "0c 60 c8 0f 96 1f 0e 71 f3 a9 b5 24 af 60 12 06 2f e0 37 a6"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha256_6() { using var hmac = new HMACSHA256(); var P = "pass\0word"; var S = "sa\0lt"; var c = 4096; var dkLen = 16; var DK = "89 b6 9d 05 16 f8 29 89 3c 69 62 26 65 0a 86 87"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha1_6() // RFC 6070 { using var hmac = new HMACSHA1(); var P = "pass\0word"; var S = "sa\0lt"; var c = 4096; var dkLen = 16; var DK = "56 fa 6a a7 55 48 09 9d cc 37 d7 f0 34 25 e0 c3"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha256_1() { using var hmac = new HMACSHA256(); var P = "password"; var S = "salt"; var c = 1; var dkLen = 32; var DK = "12 0f b6 cf fc f8 b3 2c 43 e7 22 52 56 c4 f8 37 a8 65 48 c9 2c cc 35 48 08 05 98 7c b7 0b e1 7b"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha1_2() // RFC 6070 { using var hmac = new HMACSHA1(); var P = "password"; var S = "salt"; var c = 2; var dkLen = 20; var DK = "ea 6c 01 4d c7 2d 6f 8c cd 1e d9 2a ce 1d 41 f0 d8 de 89 57"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
private byte[] DecryptHeader(byte[] headerBytes, byte[] password) { Pbkdf2 pbkdf2; KeyValuePairList <HMAC, int> hmacs = new KeyValuePairList <HMAC, int>(); hmacs.Add(new HMACSHA512(), 1000); hmacs.Add(new HMACRIPEMD160(), 2000); hmacs.Add(new HMACWhirlpool(), 1000); foreach (KeyValuePair <HMAC, int> entry in hmacs) { HMAC hmac = entry.Key; int iterations = entry.Value; pbkdf2 = new Pbkdf2(hmac, password, Salt, iterations); byte[] key = pbkdf2.GetBytes(192); List <KeyValuePairList <SymmetricAlgorithm, byte[]> > algorithms = GetAlgorithms(key); foreach (KeyValuePairList <SymmetricAlgorithm, byte[]> algorithmChain in algorithms) { byte[] decrypt = (byte[])headerBytes.Clone(); // TrueCrypt 7.1a Source (Common\Crypto.c): // ---------------------------------------- // When encrypting/decrypting a buffer (typically a volume header) the sequential number // of the first XTS data unit in the buffer is always 0 and the start of the buffer is // always assumed to be aligned with the start of the data unit 0. decrypt = XTSHelper.XTSChainDecrypt(algorithmChain, 0, decrypt, 0, 448); string signature = ByteReader.ReadAnsiString(decrypt, 0, 4); ushort formatVersion = BigEndianConverter.ToUInt16(decrypt, 4); uint checksum256 = BigEndianConverter.ToUInt32(decrypt, 8); byte[] temp = ByteReader.ReadBytes(decrypt, 192, 256); uint computedChecksum = Utilities.CRC32.Compute(temp); if (signature == TrueCryptSignature && checksum256 == computedChecksum) { m_isValid = true; if (formatVersion == SupportedFormatVersion) { m_isSupported = true; } m_algorithmChain = algorithmChain; m_hmac = hmac; return(decrypt); } } } return(null); }
public void Sha1_3() // RFC 6070 { using var hmac = new HMACSHA1(); var P = "password"; var S = "salt"; var c = 4096; var dkLen = 20; var DK = "4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha256_5() { using var hmac = new HMACSHA256(); var P = "passwordPASSWORDpassword"; var S = "saltSALTsaltSALTsaltSALTsaltSALTsalt"; var c = 4096; var dkLen = 40; var DK = "34 8c 89 db cb d3 2b 2f 32 d8 14 b8 11 6e 84 cf 2b 17 34 7e bc 18 00 18 1c 4e 2a 1f b8 dd 53 e1 c6 35 51 8c 7d ac 47 e9"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public void Sha1_5() // RFC 6070 { using var hmac = new HMACSHA1(); var P = "passwordPASSWORDpassword"; var S = "saltSALTsaltSALTsaltSALTsaltSALTsalt"; var c = 4096; var dkLen = 25; var DK = "3d 2e ec 4f e4 1c 84 9b 80 c8 d8 36 62 c0 e4 4a 8b 29 1a 96 4c f2 f0 70 38"; var df = new Pbkdf2(hmac, P, S, c); Assert.Equal(DK, BitConverter.ToString(df.GetBytes(dkLen)).Replace('-', ' ').ToLowerInvariant()); }
public static bool TestWhirlpool() { string password = "******"; byte[] passwordBytes = UTF8Encoding.UTF8.GetBytes(password); Pbkdf2 pbkdf2; HMACWhirlpool whirlpool = new HMACWhirlpool(); byte[] salt = new byte[] { 0x12, 0x34, 0x56, 0x78 }; pbkdf2 = new Pbkdf2(whirlpool, passwordBytes, salt, 5); byte[] result1 = pbkdf2.GetBytes(4); pbkdf2 = new Pbkdf2(whirlpool, passwordBytes, salt, 5); byte[] result2 = pbkdf2.GetBytes(96); byte[] hash1 = new byte[] { 0x50, 0x7c, 0x36, 0x6f }; byte[] hash2 = new byte[] { 0x50, 0x7c, 0x36, 0x6f, 0xee, 0x10, 0x2e, 0x9a, 0xe2, 0x8a, 0xd5, 0x82, 0x72, 0x7d, 0x27, 0x0f, 0xe8, 0x4d, 0x7f, 0x68, 0x7a, 0xcf, 0xb5, 0xe7, 0x43, 0x67, 0xaa, 0x98, 0x93, 0x52, 0x2b, 0x09, 0x6e, 0x42, 0xdf, 0x2c, 0x59, 0x4a, 0x91, 0x6d, 0x7e, 0x10, 0xae, 0xb2, 0x1a, 0x89, 0x8f, 0xb9, 0x8f, 0xe6, 0x31, 0xa9, 0xd8, 0x9f, 0x98, 0x26, 0xf4, 0xda, 0xcd, 0x7d, 0x65, 0x65, 0xde, 0x10, 0x95, 0x91, 0xb4, 0x84, 0x26, 0xae, 0x43, 0xa1, 0x00, 0x5b, 0x1e, 0xb8, 0x38, 0x97, 0xa4, 0x1e, 0x4b, 0xd2, 0x65, 0x64, 0xbc, 0xfa, 0x1f, 0x35, 0x85, 0xdb, 0x4f, 0x97, 0x65, 0x6f, 0xbd, 0x24 }; return(ByteUtils.AreByteArraysEqual(result1, hash1) && ByteUtils.AreByteArraysEqual(result2, hash2)); }
public static bool TestRIPEMD160() { string password = "******"; byte[] passwordBytes = UTF8Encoding.UTF8.GetBytes(password); Pbkdf2 pbkdf2; HMACRIPEMD160 ripemd160 = new HMACRIPEMD160(); byte[] salt = new byte[] { 0x12, 0x34, 0x56, 0x78 }; pbkdf2 = new Pbkdf2(ripemd160, passwordBytes, salt, 5); byte[] result1 = pbkdf2.GetBytes(4); pbkdf2 = new Pbkdf2(ripemd160, passwordBytes, salt, 5); byte[] result2 = pbkdf2.GetBytes(48); byte[] hash1 = new byte[] { 0x7a, 0x3d, 0x7c, 0x03 }; byte[] hash2 = new byte[] { 0x7a, 0x3d, 0x7c, 0x03, 0xe7, 0x26, 0x6b, 0xf8, 0x3d, 0x78, 0xfb, 0x29, 0xd2, 0x64, 0x1f, 0x56, 0xea, 0xf0, 0xe5, 0xf5, 0xcc, 0xc4, 0x3a, 0x31, 0xa8, 0x84, 0x70, 0xbf, 0xbd, 0x6f, 0x8e, 0x78, 0x24, 0x5a, 0xc0, 0x0a, 0xf6, 0xfa, 0xf0, 0xf6, 0xe9, 0x00, 0x47, 0x5f, 0x73, 0xce, 0xe1, 0x43 }; return(ByteUtils.AreByteArraysEqual(result1, hash1) && ByteUtils.AreByteArraysEqual(result2, hash2)); }
public static bool TestSHA512() { string password = "******"; byte[] passwordBytes = UTF8Encoding.UTF8.GetBytes(password); Pbkdf2 pbkdf2; HMACSHA512 sha512 = new HMACSHA512(); byte[] salt = new byte[] { 0x12, 0x34, 0x56, 0x78 }; pbkdf2 = new Pbkdf2(sha512, passwordBytes, salt, 5); byte[] result1 = pbkdf2.GetBytes(4); pbkdf2 = new Pbkdf2(sha512, passwordBytes, salt, 5); byte[] result2 = pbkdf2.GetBytes(144); byte[] hash1 = new byte[] { 0x13, 0x64, 0xae, 0xf8 }; byte[] hash2 = new byte[] { 0x13, 0x64, 0xae, 0xf8, 0x0d, 0xf5, 0x57, 0x6c, 0x30, 0xd5, 0x71, 0x4c, 0xa7, 0x75, 0x3f, 0xfd, 0x00, 0xe5, 0x25, 0x8b, 0x39, 0xc7, 0x44, 0x7f, 0xce, 0x23, 0x3d, 0x08, 0x75, 0xe0, 0x2f, 0x48, 0xd6, 0x30, 0xd7, 0x00, 0xb6, 0x24, 0xdb, 0xe0, 0x5a, 0xd7, 0x47, 0xef, 0x52, 0xca, 0xa6, 0x34, 0x83, 0x47, 0xe5, 0xcb, 0xe9, 0x87, 0xf1, 0x20, 0x59, 0x6a, 0xe6, 0xa9, 0xcf, 0x51, 0x78, 0xc6, 0xb6, 0x23, 0xa6, 0x74, 0x0d, 0xe8, 0x91, 0xbe, 0x1a, 0xd0, 0x28, 0xcc, 0xce, 0x16, 0x98, 0x9a, 0xbe, 0xfb, 0xdc, 0x78, 0xc9, 0xe1, 0x7d, 0x72, 0x67, 0xce, 0xe1, 0x61, 0x56, 0x5f, 0x96, 0x68, 0xe6, 0xe1, 0xdd, 0xf4, 0xbf, 0x1b, 0x80, 0xe0, 0x19, 0x1c, 0xf4, 0xc4, 0xd3, 0xdd, 0xd5, 0xd5, 0x57, 0x2d, 0x83, 0xc7, 0xa3, 0x37, 0x87, 0xf4, 0x4e, 0xe0, 0xf6, 0xd8, 0x6d, 0x65, 0xdc, 0xa0, 0x52, 0xa3, 0x13, 0xbe, 0x81, 0xfc, 0x30, 0xbe, 0x7d, 0x69, 0x58, 0x34, 0xb6, 0xdd, 0x41, 0xc6 }; return(ByteUtils.AreByteArraysEqual(result1, hash1) && ByteUtils.AreByteArraysEqual(result2, hash2)); }
public static string HashPassword(string pass, string salt) { int passIterations = 12000; var hashed = String.Empty; using (var hmac = new HMACSHA256()) { var df = new Pbkdf2(hmac, pass, salt, passIterations); String passEncrypted = Convert.ToBase64String(df.GetBytes(32)); hashed = String.Format("pbkdf2_sha256${0}${1}${2}", passIterations, salt, passEncrypted); } return(hashed); }
/// <summary> /// Including the prefixed salt /// </summary> public byte[] GetBytes(byte[] password) { byte[] headerBytes = GetDecryptedHeaderBytes(); int iterations = m_hmac is HMACRIPEMD160 ? 2000 : 1000; Pbkdf2 pbkdf2 = new Pbkdf2(m_hmac, password, Salt, iterations); byte[] headerKey = pbkdf2.GetBytes(192); AssignKey(m_algorithmChain, headerKey); byte[] encrypted = XTSHelper.XTSChainEncrypt(m_algorithmChain, 0, headerBytes, 0, headerBytes.Length); AssignKey(m_algorithmChain, MasterKey); byte[] buffer = new byte[512]; ByteWriter.WriteBytes(buffer, 0, Salt); ByteWriter.WriteBytes(buffer, 64, encrypted); return(buffer); }
private static sbyte[] Pbk(string hash, string password, string salt, int iterations) { try { byte[] saltBytes = Convert.FromBase64String(salt); using (var hmac = new HMACSHA256()) { var mine = new Pbkdf2(hmac, Encoding.UTF8.GetBytes(password), (byte[])(Array)Convert.FromBase64String(salt), iterations); sbyte[] signed = mine.GetBytes(32); byte[] signednew = (byte[])(Array)signed; return(signed); } } catch (Exception e) { throw e; } }
private static sbyte[] Pbk(string hash, string password, string salt, int iterations) { try { byte[] saltBytes = Base64.STANDARD.DecodeBytes(salt); using (var hmac = new HMACSHA256()) { var mine = new Pbkdf2(hmac, System.Text.Encoding.UTF8.GetBytes(password), (byte[])(Array)Base64.STANDARD.DecodeBytes(salt), iterations); sbyte[] signed = mine.GetBytes(32); byte[] signednew = (byte[])(Array)signed; return(signed); } } catch (Exception e) { throw e; } }
public Credentials(string email, string password) { Email = email; using (var hmac = new HMACSHA256()) { Pbkdf2 pbkdf2 = new Pbkdf2(hmac, Encoding.UTF8.GetBytes(password), BinaryHelper.Kwe("quickStretch", email), 1000); QuickStretchedPW = pbkdf2.GetBytes(32); HKDF hkdf = new HKDF(hmac, QuickStretchedPW); AuthPW = hkdf.Expand(BinaryHelper.Kw("authPW"), 32); UnwrapBKey = hkdf.Expand(BinaryHelper.Kw("unwrapBkey"), 32); } using (SHA256 sha256 = new SHA256()) { byte[] hash = sha256.ComputeHash(UnwrapBKey); SyncClientState = BinaryHelper.ToHexString(hash.Take(16).ToArray()); } }
public PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) { string[] oldpw = hashedPassword.Split(":".ToCharArray()); byte[] salt = Convert.FromBase64String(oldpw[1]); Pbkdf2 pbkdf2 = new Pbkdf2(new HMACSHA256(), System.Text.Encoding.UTF8.GetBytes(providedPassword), salt); if (Convert.ToBase64String(pbkdf2.GetBytes(32)) == oldpw[0]) { return(PasswordVerificationResult.Success); } // TODO: Implement converting of old phpBB passwords // Possible Implementation is here https://www.phpbb.com/community/viewtopic.php?f=71&t=1771165, but cannot be used due to licensing issues. //if (cPhpBB.phpbbCheckHash(providedPassword, hashedPassword)) // return PasswordVerificationResult.SuccessRehashNeeded; return(PasswordVerificationResult.Failed); }
public override void Connect(TimeSpan timeout, Information options) { if (_disposed) { throw new ObjectDisposedException(this.GetType().FullName); } lock (this.ThisLock) { try { SecureVersion3.ProtocolInformation myProtocol3; SecureVersion3.ProtocolInformation otherProtocol3; { OperatingSystem osInfo = Environment.OSVersion; // Windows Vista�ȏ�B if (osInfo.Platform == PlatformID.Win32NT && osInfo.Version >= new Version(6, 0)) { { byte[] sessionId = new byte[32]; _random.GetBytes(sessionId); myProtocol3 = new SecureVersion3.ProtocolInformation() { KeyExchangeAlgorithm = SecureVersion3.KeyExchangeAlgorithm.EcDiffieHellmanP521 | SecureVersion3.KeyExchangeAlgorithm.Rsa2048, KeyDerivationAlgorithm = SecureVersion3.KeyDerivationAlgorithm.Pbkdf2, CryptoAlgorithm = SecureVersion3.CryptoAlgorithm.Aes256, HashAlgorithm = SecureVersion3.HashAlgorithm.Sha256, SessionId = sessionId, }; } } else { { byte[] sessionId = new byte[32]; _random.GetBytes(sessionId); myProtocol3 = new SecureVersion3.ProtocolInformation() { KeyExchangeAlgorithm = SecureVersion3.KeyExchangeAlgorithm.Rsa2048, KeyDerivationAlgorithm = SecureVersion3.KeyDerivationAlgorithm.Pbkdf2, CryptoAlgorithm = SecureVersion3.CryptoAlgorithm.Aes256, HashAlgorithm = SecureVersion3.HashAlgorithm.Sha256, SessionId = sessionId, }; } } } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); using (BufferStream stream = new BufferStream(_bufferManager)) using (XmlTextWriter xml = new XmlTextWriter(stream, new UTF8Encoding(false))) { xml.WriteStartDocument(); xml.WriteStartElement("Protocol"); if (_myVersion.HasFlag(SecureConnectionVersion.Version3)) { xml.WriteStartElement("SecureConnection"); xml.WriteAttributeString("Version", "3"); xml.WriteEndElement(); //Protocol } xml.WriteEndElement(); //Configuration xml.WriteEndDocument(); xml.Flush(); stream.Flush(); stream.Seek(0, SeekOrigin.Begin); _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout)); } otherProtocol3 = new SecureVersion3.ProtocolInformation(); using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout))) using (XmlTextReader xml = new XmlTextReader(stream)) { while (xml.Read()) { if (xml.NodeType == XmlNodeType.Element) { if (xml.LocalName == "SecureConnection") { if (xml.GetAttribute("Version") == "3") { _otherVersion |= SecureConnectionVersion.Version3; } } } } } _version = _myVersion & _otherVersion; // Version3 if (_version.HasFlag(SecureConnectionVersion.Version3)) { using (Stream stream = myProtocol3.Export(_bufferManager)) { _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout)); } using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout))) { otherProtocol3 = SecureVersion3.ProtocolInformation.Import(stream, _bufferManager); } var keyExchangeAlgorithm = myProtocol3.KeyExchangeAlgorithm & otherProtocol3.KeyExchangeAlgorithm; var keyDerivationFunctionAlgorithm = myProtocol3.KeyDerivationAlgorithm & otherProtocol3.KeyDerivationAlgorithm; var cryptoAlgorithm = myProtocol3.CryptoAlgorithm & otherProtocol3.CryptoAlgorithm; var hashAlgorithm = myProtocol3.HashAlgorithm & otherProtocol3.HashAlgorithm; byte[] myCryptoKey; byte[] otherCryptoKey; byte[] myHmacKey; byte[] otherHmacKey; byte[] myProtocolHash = null; byte[] otherProtocolHash = null; if (hashAlgorithm.HasFlag(SecureVersion3.HashAlgorithm.Sha256)) { using (var myProtocolHashStream = myProtocol3.Export(_bufferManager)) using (var otherProtocolHashStream = otherProtocol3.Export(_bufferManager)) { myProtocolHash = Sha256.ComputeHash(myProtocolHashStream); otherProtocolHash = Sha256.ComputeHash(otherProtocolHashStream); } } byte[] seed = null; if (keyExchangeAlgorithm.HasFlag(SecureVersion3.KeyExchangeAlgorithm.EcDiffieHellmanP521)) { byte[] publicKey, privateKey; EcDiffieHellmanP521.CreateKeys(out publicKey, out privateKey); { SecureVersion3.ConnectionSignature connectionSignature = new SecureVersion3.ConnectionSignature(); connectionSignature.ExchangeKey = publicKey; if (_digitalSignature != null) { connectionSignature.CreationTime = DateTime.UtcNow; connectionSignature.ProtocolHash = myProtocolHash; connectionSignature.CreateCertificate(_digitalSignature); } using (Stream stream = connectionSignature.Export(_bufferManager)) { _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout)); } } byte[] otherPublicKey = null; using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout))) { SecureVersion3.ConnectionSignature connectionSignature = SecureVersion3.ConnectionSignature.Import(stream, _bufferManager); if (connectionSignature.VerifyCertificate()) { if (connectionSignature.Certificate != null) { DateTime now = DateTime.UtcNow; TimeSpan span = (now > connectionSignature.CreationTime) ? now - connectionSignature.CreationTime : connectionSignature.CreationTime - now; if (span > new TimeSpan(0, 30, 0)) { throw new ConnectionException(); } if (!Unsafe.Equals(connectionSignature.ProtocolHash, otherProtocolHash)) { throw new ConnectionException(); } } _certificate = connectionSignature.Certificate; otherPublicKey = connectionSignature.ExchangeKey; } else { throw new ConnectionException(); } } if (hashAlgorithm.HasFlag(SecureVersion3.HashAlgorithm.Sha256)) { seed = EcDiffieHellmanP521.DeriveKeyMaterial(privateKey, otherPublicKey, CngAlgorithm.Sha256); } if (seed == null) { throw new ConnectionException(); } } else if (keyExchangeAlgorithm.HasFlag(SecureVersion3.KeyExchangeAlgorithm.Rsa2048)) { byte[] publicKey, privateKey; Rsa2048.CreateKeys(out publicKey, out privateKey); { SecureVersion3.ConnectionSignature connectionSignature = new SecureVersion3.ConnectionSignature(); connectionSignature.ExchangeKey = publicKey; if (_digitalSignature != null) { connectionSignature.CreationTime = DateTime.UtcNow; connectionSignature.ProtocolHash = myProtocolHash; connectionSignature.CreateCertificate(_digitalSignature); } using (Stream stream = connectionSignature.Export(_bufferManager)) { _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout)); } } byte[] otherPublicKey; using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout))) { SecureVersion3.ConnectionSignature connectionSignature = SecureVersion3.ConnectionSignature.Import(stream, _bufferManager); if (connectionSignature.VerifyCertificate()) { if (connectionSignature.Certificate != null) { DateTime now = DateTime.UtcNow; TimeSpan span = (now > connectionSignature.CreationTime) ? now - connectionSignature.CreationTime : connectionSignature.CreationTime - now; if (span > new TimeSpan(0, 30, 0)) { throw new ConnectionException(); } if (!Unsafe.Equals(connectionSignature.ProtocolHash, otherProtocolHash)) { throw new ConnectionException(); } } _certificate = connectionSignature.Certificate; otherPublicKey = connectionSignature.ExchangeKey; } else { throw new ConnectionException(); } } byte[] mySeed = new byte[128]; _random.GetBytes(mySeed); using (MemoryStream stream = new MemoryStream(Rsa2048.Encrypt(otherPublicKey, mySeed))) { _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout)); } byte[] otherSeed; using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout))) { var buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); otherSeed = Rsa2048.Decrypt(privateKey, buffer); } if (otherSeed == null) { throw new ConnectionException(); } seed = new byte[Math.Max(mySeed.Length, otherSeed.Length)]; Unsafe.Xor(mySeed, otherSeed, seed); } else { throw new ConnectionException(); } if (keyDerivationFunctionAlgorithm.HasFlag(SecureVersion3.KeyDerivationAlgorithm.Pbkdf2)) { byte[] xorSessionId = new byte[Math.Max(myProtocol3.SessionId.Length, otherProtocol3.SessionId.Length)]; Unsafe.Xor(myProtocol3.SessionId, otherProtocol3.SessionId, xorSessionId); HMAC hmac = null; if (hashAlgorithm.HasFlag(SecureVersion3.HashAlgorithm.Sha256)) { hmac = new HMACSHA256(); hmac.HashName = "SHA256"; } else { throw new ConnectionException(); } Pbkdf2 pbkdf2 = new Pbkdf2(hmac, seed, xorSessionId, 1024); int cryptoKeyLength; int hmacKeyLength; if (cryptoAlgorithm.HasFlag(SecureVersion3.CryptoAlgorithm.Aes256)) { cryptoKeyLength = 32; } else { throw new ConnectionException(); } if (hashAlgorithm.HasFlag(SecureVersion3.HashAlgorithm.Sha256)) { hmacKeyLength = 32; } else { throw new ConnectionException(); } myCryptoKey = new byte[cryptoKeyLength]; otherCryptoKey = new byte[cryptoKeyLength]; myHmacKey = new byte[hmacKeyLength]; otherHmacKey = new byte[hmacKeyLength]; using (MemoryStream stream = new MemoryStream(pbkdf2.GetBytes((cryptoKeyLength + hmacKeyLength) * 2))) { if (_type == SecureConnectionType.Connect) { stream.Read(myCryptoKey, 0, myCryptoKey.Length); stream.Read(otherCryptoKey, 0, otherCryptoKey.Length); stream.Read(myHmacKey, 0, myHmacKey.Length); stream.Read(otherHmacKey, 0, otherHmacKey.Length); } else if (_type == SecureConnectionType.Accept) { stream.Read(otherCryptoKey, 0, otherCryptoKey.Length); stream.Read(myCryptoKey, 0, myCryptoKey.Length); stream.Read(otherHmacKey, 0, otherHmacKey.Length); stream.Read(myHmacKey, 0, myHmacKey.Length); } else { throw new ConnectionException(); } } } else { throw new ConnectionException(); } _informationVersion3 = new InformationVersion3(); _informationVersion3.CryptoAlgorithm = cryptoAlgorithm; _informationVersion3.HashAlgorithm = hashAlgorithm; _informationVersion3.MyCryptoKey = myCryptoKey; _informationVersion3.OtherCryptoKey = otherCryptoKey; _informationVersion3.MyHmacKey = myHmacKey; _informationVersion3.OtherHmacKey = otherHmacKey; } else { throw new ConnectionException(); } } catch (ConnectionException e) { throw e; } catch (Exception e) { throw new ConnectionException(e.Message, e); } _connect = true; } }
public static Dictionary <string, string> DecryptMasterKeyWithSha(byte[] masterKeyBytes, byte[] shaBytes) { // takes masterkey bytes and SYSTEM_DPAPI masterkey sha bytes, returns a dictionary of guid:sha1 masterkey mappings Dictionary <string, string> mapping = new Dictionary <string, string>(); try { string guidMasterKey = String.Format("{{{0}}}", Encoding.Unicode.GetString(masterKeyBytes, 12, 72)); byte[] mkBytes = GetMasterKey(masterKeyBytes); int offset = 4; byte[] salt = new byte[16]; Array.Copy(mkBytes, 4, salt, 0, 16); offset += 16; int rounds = BitConverter.ToInt32(mkBytes, offset); offset += 4; int algHash = BitConverter.ToInt32(mkBytes, offset); offset += 4; int algCrypt = BitConverter.ToInt32(mkBytes, offset); offset += 4; byte[] encData = new byte[mkBytes.Length - offset]; Array.Copy(mkBytes, offset, encData, 0, encData.Length); byte[] final = new byte[48]; if (algHash == 32782) { // derive the "Pbkdf2/SHA512" key for the masterkey, using MS' silliness using (var hmac = new HMACSHA512()) { var df = new Pbkdf2(hmac, shaBytes, salt, rounds); final = df.GetBytes(48); } } else { Console.WriteLine("[X] Note: alg hash '{0} / 0x{1}' not currently supported!", algHash, algHash.ToString("X8")); } // CALG_AES_256 == 26128 if (algCrypt == 26128) { AesManaged aesCryptoProvider = new AesManaged(); byte[] ivBytes = new byte[16]; Array.Copy(final, 32, ivBytes, 0, 16); byte[] key = new byte[32]; Array.Copy(final, 0, key, 0, 32); aesCryptoProvider.Key = key; aesCryptoProvider.IV = ivBytes; aesCryptoProvider.Mode = CipherMode.CBC; aesCryptoProvider.Padding = PaddingMode.Zeros; byte[] plaintextBytes = aesCryptoProvider.CreateDecryptor().TransformFinalBlock(encData, 0, encData.Length); byte[] masterKeyFull = new byte[64]; Array.Copy(plaintextBytes, 80, masterKeyFull, 0, masterKeyFull.Length); //Console.WriteLine("MasterKey (full): {0}", BitConverter.ToString(masterKeyFull).Replace("-", "")); using (SHA1Managed sha1 = new SHA1Managed()) { byte[] masterKeySha1 = sha1.ComputeHash(masterKeyFull); string masterKeySha1Hex = BitConverter.ToString(masterKeySha1).Replace("-", ""); //Console.WriteLine("MasterKey (sha1): {0}", BitConverter.ToString(masterKeySha1).Replace("-", "")); mapping.Add(guidMasterKey, masterKeySha1Hex); } // f**k the HMAC integrity checking for now LOL ;) //byte[] plaintextCryptBuffer = new byte[16]; //Array.Copy(plaintextBytes, 0, plaintextBytes, 0, 16); //HMACSHA512 hmac = new HMACSHA512(shaBytes); // key bytes //byte[] round1bytes = hmac.ComputeHash(plaintextCryptBuffer); // salt bytes //Console.WriteLine("round1bytes: {0}", BitConverter.ToString(round1bytes).Replace("-", "")); } else { Console.WriteLine("[X] Note: alg crypt '{0} / 0x{1}' not currently supported!", algCrypt, algCrypt.ToString("X8")); } } catch { } return(mapping); }
public static Dictionary <string, string> DecryptMasterKeyWithSha(byte[] masterKeyBytes, byte[] shaBytes) { // takes masterkey bytes and SYSTEM_DPAPI masterkey sha bytes, returns a dictionary of guid:sha1 masterkey mappings Dictionary <string, string> mapping = new Dictionary <string, string>(); try { string guidMasterKey = String.Format("{{{0}}}", Encoding.Unicode.GetString(masterKeyBytes, 12, 72)); byte[] mkBytes = GetMasterKey(masterKeyBytes); int offset = 4; byte[] salt = new byte[16]; Array.Copy(mkBytes, 4, salt, 0, 16); offset += 16; int rounds = BitConverter.ToInt32(mkBytes, offset); offset += 4; int algHash = BitConverter.ToInt32(mkBytes, offset); offset += 4; int algCrypt = BitConverter.ToInt32(mkBytes, offset); offset += 4; byte[] encData = new byte[mkBytes.Length - offset]; Array.Copy(mkBytes, offset, encData, 0, encData.Length); byte[] final = new byte[48]; // CALG_SHA_512 == 32782 if (algHash == 32782) { // derive the "Pbkdf2/SHA512" key for the masterkey, using MS' silliness using (var hmac = new HMACSHA512()) { var df = new Pbkdf2(hmac, shaBytes, salt, rounds); final = df.GetBytes(48); } } else { Console.WriteLine("[X] Note: alg hash '{0} / 0x{1}' not currently supported!", algHash, algHash.ToString("X8")); return(mapping); } // TODO: support more than just CALG_AES_256 and CALG_SHA_512 ! // CALG_AES_256 == 26128 , CALG_SHA_512 == 32782 if ((algCrypt == 26128) && (algHash == 32782)) { int HMACLen = (new HMACSHA512()).HashSize / 8; AesManaged aesCryptoProvider = new AesManaged(); byte[] ivBytes = new byte[16]; Array.Copy(final, 32, ivBytes, 0, 16); byte[] key = new byte[32]; Array.Copy(final, 0, key, 0, 32); aesCryptoProvider.Key = key; aesCryptoProvider.IV = ivBytes; aesCryptoProvider.Mode = CipherMode.CBC; aesCryptoProvider.Padding = PaddingMode.Zeros; // decrypt the encrypted data using the Pbkdf2-derived key byte[] plaintextBytes = aesCryptoProvider.CreateDecryptor().TransformFinalBlock(encData, 0, encData.Length); int outLen = plaintextBytes.Length; int outputLen = outLen - 16 - HMACLen; byte[] masterKeyFull = new byte[HMACLen]; // outLen - outputLen == 80 in this case Array.Copy(plaintextBytes, outLen - outputLen, masterKeyFull, 0, masterKeyFull.Length); using (SHA1Managed sha1 = new SHA1Managed()) { byte[] masterKeySha1 = sha1.ComputeHash(masterKeyFull); string masterKeySha1Hex = BitConverter.ToString(masterKeySha1).Replace("-", ""); // CALG_SHA_512 == 32782 if (algHash == 32782) { // we're HMAC'ing the first 16 bytes of the decrypted buffer with the shaBytes as the key byte[] plaintextCryptBuffer = new byte[16]; Array.Copy(plaintextBytes, plaintextCryptBuffer, 16); HMACSHA512 hmac1 = new HMACSHA512(shaBytes); byte[] round1Hmac = hmac1.ComputeHash(plaintextCryptBuffer); // round 2 byte[] round2buffer = new byte[outputLen]; Array.Copy(plaintextBytes, outLen - outputLen, round2buffer, 0, outputLen); HMACSHA512 hmac2 = new HMACSHA512(round1Hmac); byte[] round2Hmac = hmac2.ComputeHash(round2buffer); // compare the second HMAC value to the original plaintextBytes, starting at index 16 byte[] comparison = new byte[64]; Array.Copy(plaintextBytes, 16, comparison, 0, comparison.Length); string s1 = BitConverter.ToString(comparison).Replace("-", ""); string s2 = BitConverter.ToString(round2Hmac).Replace("-", ""); if (s1.Equals(s2)) { mapping.Add(guidMasterKey, masterKeySha1Hex); } else { Console.WriteLine("[X] {0}:{1} - HMAC integrity check failed!", guidMasterKey, masterKeySha1Hex); return(mapping); } } else { Console.WriteLine("[X] Note: alg hash '{0} / 0x{1}' not currently supported!", algHash, algHash.ToString("X8")); return(mapping); } } } else { Console.WriteLine("[X] Note: alg crypt '{0} / 0x{1}' not currently supported!", algCrypt, algCrypt.ToString("X8")); return(mapping); } } catch { } return(mapping); }