예제 #1
0
        public override ReadOnlyMemory <byte> Encrypt(ReadOnlyMemory <byte> data, KerberosKey key, KeyUsage usage)
        {
            var k1 = key.GetKey(this);

            var salt = GetSalt((int)usage);

            var k2 = HMACMD5(k1, salt);

            var confounder = GenerateRandomBytes(ConfounderSize);

            var plaintextBuffer = new byte[data.Length + confounder.Length];
            var plaintext       = new Memory <byte>(plaintextBuffer);

            confounder.CopyTo(plaintext);
            data.CopyTo(plaintext.Slice(confounder.Length));

            var checksum = HMACMD5(k2, plaintextBuffer);

            var k3 = HMACMD5(k2, checksum);

            var ciphertext = new Memory <byte>(new byte[plaintext.Length + checksum.Length]);

            RC4.Transform(k3.Span, plaintext.Span, ciphertext.Span.Slice(checksum.Length));

            checksum.CopyTo(ciphertext);

            return(ciphertext);
        }
예제 #2
0
        public override ReadOnlyMemory <byte> Decrypt(ReadOnlyMemory <byte> ciphertext, KerberosKey key, KeyUsage usage)
        {
            var k1 = key.GetKey(this);

            var salt = GetSalt((int)usage);

            var k2 = HMACMD5(k1, salt);

            var incomingChecksum = ciphertext.Slice(0, HashSize);

            var k3 = HMACMD5(k2, incomingChecksum);

            var ciphertextOffset = ciphertext.Slice(HashSize);

            var plaintext = new Memory <byte>(new byte[ciphertextOffset.Length]);

            RC4.Transform(k3.Span, ciphertextOffset.Span, plaintext.Span);

            var actualChecksum = HMACMD5(k2, plaintext);

            if (!AreEqualSlow(incomingChecksum.Span, actualChecksum.Span.Slice(0, actualChecksum.Length)))
            {
                throw new SecurityException("Invalid Checksum");
            }

            return(plaintext.Slice(ConfounderSize));
        }
예제 #3
0
        public override byte[] Decrypt(ReadOnlyMemory <byte> ciphertext, KerberosKey key, KeyUsage usage)
        {
            var k1 = key.GetKey(this);

            var salt = GetSalt((int)usage);

            var k2 = HMACMD5(k1, salt);

            var checksum = new byte[HashSize];

            Buffer.BlockCopy(ciphertext.ToArray(), 0, checksum, 0, HashSize);

            var k3 = HMACMD5(k2, checksum);

            var ciphertextOffset = new byte[ciphertext.Length - HashSize];

            Buffer.BlockCopy(ciphertext.ToArray(), HashSize, ciphertextOffset, 0, ciphertextOffset.Length);

            var plaintext = RC4.Transform(k3, ciphertextOffset);

            var actualChecksum = HMACMD5(k2, plaintext.ToArray());

            if (!AreEqualSlow(checksum, ciphertext.ToArray(), actualChecksum.Length))
            {
                throw new SecurityException("Invalid Checksum");
            }

            var output = new byte[plaintext.Length - ConfounderSize];

            Buffer.BlockCopy(plaintext.ToArray(), ConfounderSize, output, 0, output.Length);

            return(output);
        }
예제 #4
0
        protected override ReadOnlySpan <byte> SignInternal(KerberosKey key)
        {
            var crypto = CryptoService.CreateTransform(EncryptionType.RC4_HMAC_NT);

            return(crypto.MakeChecksum(
                       key.GetKey(crypto),
                       Pac.Span,
                       KeyUsage.PaForUserChecksum
                       ));
        }
예제 #5
0
 protected override ReadOnlyMemory <byte> SignInternal(KerberosKey key)
 {
     return(decryptor.MakeChecksum(
                Pac.ToArray(),
                key.GetKey(decryptor),
                KeyUsage.PaForUserChecksum,
                KeyDerivationMode.Kc,
                decryptor.ChecksumSize
                ));
 }
예제 #6
0
        protected override ReadOnlyMemory <byte> SignInternal(KerberosKey key)
        {
            var crypto = CryptoService.CreateTransform(EncryptionType.RC4_HMAC_NT);

            return(crypto.MakeChecksum(
                       key.GetKey(crypto),
                       Data.Span,
                       Usage
                       ));
        }
예제 #7
0
        protected override bool ValidateInternal(KerberosKey key)
        {
            var actualChecksum = KerberosHash.KerbChecksumHmacMd5(
                key.GetKey(new MD4Encryptor()),
                (int)KeyUsage.KU_PA_FOR_USER_ENC_CKSUM,
                Pac
                );

            return(KerberosHash.AreEqualSlow(actualChecksum, Signature));
        }
예제 #8
0
        protected override bool ValidateInternal(KerberosKey key)
        {
            var constant = new byte[5];

            KerberosHash.ConvertToBigEndian((int)KeyUsage.KU_PA_FOR_USER_ENC_CKSUM, constant, 0);

            constant[4] = 0x99;

            var Ki = encryptor.DK(key.GetKey(encryptor), constant);

            var actualChecksum = decryptor.MakeChecksum(Ki, Pac, decryptor.ChecksumSize);

            return(KerberosHash.AreEqualSlow(actualChecksum, Signature));
        }
예제 #9
0
        public override int ChecksumSize => 16; // bytes

        protected override ReadOnlyMemory <byte> SignInternal(KerberosKey key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var crypto = CryptoService.CreateTransform(EncryptionType.RC4_HMAC_NT);

            return(crypto.MakeChecksum(
                       key.GetKey(crypto),
                       this.Data.Span,
                       this.Usage
                       ));
        }
예제 #10
0
        public override ReadOnlyMemory <byte> Encrypt(ReadOnlyMemory <byte> data, KerberosKey key, KeyUsage usage)
        {
            var k1 = key.GetKey(this);

            var salt = GetSalt((int)usage);

            var k2 = HMACMD5(k1, salt);

            var confounder = GenerateRandomBytes(ConfounderSize);

            var plaintext = new byte[data.Length + confounder.Length];

            Buffer.BlockCopy(confounder.ToArray(), 0, plaintext, 0, confounder.Length);
            Buffer.BlockCopy(data.ToArray(), 0, plaintext, confounder.Length, data.Length);

            var checksum = HMACMD5(k2, plaintext);

            var k3 = HMACMD5(k2, checksum);

            var ciphertext = RC4.Transform(k3, plaintext);

            return(new ReadOnlyMemory <byte>(checksum.Concat(ciphertext.ToArray()).ToArray()));
        }
예제 #11
0
        private static void WriteKey(BinaryWriter writer, KerberosKey key)
        {
            WriteInt16(writer, (short)key.EncryptionType);

            WriteBytes(writer, key.GetKey());
        }