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));
        }
Exemple #2
0
        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));
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        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()));
        }
Exemple #6
0
        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));
        }
Exemple #7
0
        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));
        }
Exemple #8
0
        public override byte[] Decrypt(byte[] cipher, KerberosKey key, KeyUsage usage)
        {
            var iv = new byte[Encryptor.BlockSize];

            return(Decrypt(cipher, key.GetKey(Encryptor), iv, usage));
        }