public override byte[] Decrypt(ReadOnlyMemory <byte> cipher, KerberosKey kerberosKey, KeyUsage usage) { var key = kerberosKey.GetKey(this); var cipherLength = cipher.Length - ChecksumSize; var Ke = DK(key, usage, KeyDerivationMode.Ke); var decrypted = AESCTS.Decrypt( BlockCopy(cipher, 0, cipherLength), Ke, AllZerosInitVector ); var actualChecksum = MakeChecksum(decrypted, key, usage, KeyDerivationMode.Ki, ChecksumSize); var expectedChecksum = BlockCopy(cipher, cipherLength, ChecksumSize); if (!AreEqualSlow(expectedChecksum, actualChecksum)) { throw new SecurityException("Invalid checksum"); } return(BlockCopy(decrypted, ConfounderSize, cipherLength - ConfounderSize)); }
public void MsKileInterop() { var rawKey = new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; // DOMAIN.COMhostclient.domain.com var key = new KerberosKey( password: rawKey, host: "client", principal: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "domain.com", new[] { "client" }), etype: EncryptionType.AES128_CTS_HMAC_SHA1_96, iterationParams: new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8 } ); var expectedKey = new byte[] { 0xb8, 0x2e, 0xe1, 0x22, 0x53, 0x1c, 0x2d, 0x94, 0x82, 0x1a, 0xc7, 0x55, 0xbc, 0xcb, 0x58, 0x79 }; var gen = key.GetKey(); Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(gen.Span, expectedKey)); }
private static void AssertSaltGeneration(EncryptionType etype, SaltType saltType, byte[] expectedKey) { var key = new KerberosKey( "P@ssw0rd!", principalName: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "domain.com", new string[] { "appservice" }), host: "appservice", etype: etype, saltType: saltType ); Assert.AreEqual(saltType, key.SaltFormat); var gen = key.GetKey(); Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(gen.Span, expectedKey)); }
private static void AssertKeyMatchesGuid(EncryptionType etype, KerberosKey kerbKey) { Assert.AreEqual(EncryptionType.AES256_CTS_HMAC_SHA1_96, etype); var derivedKey = kerbKey.GetKey(null); Assert.IsNotNull(derivedKey); var expectedKey = new byte[] { 0xbc, 0x31, 0x7e, 0x82, 0x48, 0x55, 0xcb, 0xa0, 0x3f, 0x70, 0xbe, 0x93, 0x0a, 0xa5, 0x0f, 0xef, 0x6a, 0x64, 0x7c, 0xc3, 0x99, 0x36, 0x63, 0xee, 0xa5, 0x39, 0x2f, 0xab, 0xd9, 0x01, 0xad, 0xce }; Assert.IsTrue(expectedKey.SequenceEqual(derivedKey.ToArray())); }
public override ReadOnlyMemory <byte> Encrypt(ReadOnlyMemory <byte> data, KerberosKey kerberosKey, KeyUsage usage) { var key = kerberosKey.GetKey(this); var Ke = DK(key, usage, KeyDerivationMode.Ke); var cleartext = new Memory <byte>(new byte[ConfounderSize + data.Length]); var confounder = GenerateRandomBytes(ConfounderSize); confounder.CopyTo(cleartext.Slice(0, ConfounderSize)); data.CopyTo(cleartext.Slice(ConfounderSize, data.Length)); var encrypted = AESCTS.Encrypt( cleartext.ToArray(), Ke, AllZerosInitVector ); var checksum = MakeChecksum(cleartext.ToArray(), key, usage, KeyDerivationMode.Ki, ChecksumSize); return(new ReadOnlyMemory <byte>(encrypted.Concat(checksum).ToArray())); }
private static void Rfc4120TestCase( int iterationCount, string password, string salt, PrincipalName principal, byte[] expectedKey, EncryptionType etype ) { byte[] iterations = BitConverter.GetBytes(iterationCount); Array.Reverse(iterations); var keyFixedSalt = new KerberosKey( password: password, salt: salt, etype: etype, iterationParams: iterations ); var fixedKey = keyFixedSalt.GetKey(); Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(fixedKey.Span, expectedKey)); var keyDerivedSalt = new KerberosKey( password: password, principalName: principal, etype: etype, iterationParams: iterations, saltType: SaltType.Rfc4120 ); var derived = keyDerivedSalt.GetKey(); Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(derived.Span, expectedKey)); }
public void AssertRfc4120CaseSensitivity() { var lowerCaseKey = new KerberosKey( "P@ssw0rd!", principalName: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "domain.com", new string[] { "appservice" }), host: "appservice", etype: EncryptionType.AES128_CTS_HMAC_SHA1_96, saltType: SaltType.Rfc4120 ); var lowerCase = lowerCaseKey.GetKey(); var upperCaseKey = new KerberosKey( "P@ssw0rd!", principalName: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "DOMAIN.COM", new string[] { "appservice" }), host: "appservice", etype: EncryptionType.AES128_CTS_HMAC_SHA1_96, saltType: SaltType.Rfc4120 ); var upperCase = upperCaseKey.GetKey(); Assert.IsFalse(KerberosCryptoTransformer.AreEqualSlow(lowerCase.Span, upperCase.Span)); }
public override byte[] Decrypt(byte[] cipher, KerberosKey key, KeyUsage usage) { var iv = new byte[Encryptor.BlockSize]; return(Decrypt(cipher, key.GetKey(Encryptor), iv, usage)); }