private bool Verify(int version, string privateMac, string privateHash, SecureString passphrase, string keyTypeName, string encryptionName, string comment, byte[] publicBlob, byte[] privateBlob) { byte[] macData; using (MemoryStream macDataBuff = new MemoryStream()) { if (version == 1) { WriteMacData(macDataBuff, privateBlob); } else { WriteMacData(macDataBuff, keyTypeName); WriteMacData(macDataBuff, encryptionName); WriteMacData(macDataBuff, comment); WriteMacData(macDataBuff, publicBlob); WriteMacData(macDataBuff, privateBlob); } macDataBuff.Close(); macData = macDataBuff.ToArray(); } if (privateMac != null) { var sha1 = new SHA1CryptoServiceProvider(); var a = Encoding.ASCII.GetBytes("putty-private-key-file-mac-key"); sha1.TransformBlock(a, 0, a.Length, null, 0); //var b = Encoding.UTF8.GetBytes(passphrase); //sha1.TransformFinalBlock(b, 0, b.Length); sha1.HashBlock(passphrase, true); var key = sha1.Hash; sha1.Clear(); var hmacsha1 = new HMACSHA1(key); byte[] hash = hmacsha1.ComputeHash(macData); hmacsha1.Clear(); string mac = BinToHex(hash); return mac == privateMac; } if (privateHash == null) return true; var sha2 = new SHA1CryptoServiceProvider(); var hash2 = sha2.ComputeHash(macData); sha2.Clear(); var mac2 = BinToHex(hash2); return mac2 == privateHash; }
private static byte[] PuTTYPassphraseToKey(SecureString passphrase) { const int HASH_SIZE = 20; SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); //byte[] pp = Encoding.UTF8.GetBytes(passphrase); byte[] buf = new byte[HASH_SIZE * 2]; sha1.TransformBlock(new byte[] { 0, 0, 0, 0 }, 0, 4, null, 0); sha1.HashBlock(passphrase, true); //sha1.TransformFinalBlock(pp, 0, pp.Length); Buffer.BlockCopy(sha1.Hash, 0, buf, 0, HASH_SIZE); sha1.Initialize(); sha1.TransformBlock(new byte[] { 0, 0, 0, 1 }, 0, 4, null, 0); sha1.HashBlock(passphrase, true); //sha1.TransformFinalBlock(pp, 0, pp.Length); Buffer.BlockCopy(sha1.Hash, 0, buf, HASH_SIZE, HASH_SIZE); sha1.Clear(); byte[] key = new byte[32]; Buffer.BlockCopy(buf, 0, key, 0, key.Length); return key; }