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)); }
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); }
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); }
private static byte[] Decrypt(byte[] k1, byte[] ciphertext, KeyUsage keyType) { var salt = GetSalt((int)keyType); var k2 = KerberosHash.HMACMD5(k1, salt); var checksum = new byte[HashSize]; Buffer.BlockCopy(ciphertext, 0, checksum, 0, HashSize); var k3 = KerberosHash.HMACMD5(k2, checksum); var ciphertextOffset = new byte[ciphertext.Length - HashSize]; Buffer.BlockCopy(ciphertext, HashSize, ciphertextOffset, 0, ciphertextOffset.Length); var plaintext = RC4.Decrypt(k3, ciphertextOffset); var calculatedHmac = KerberosHash.HMACMD5(k2, plaintext); if (!KerberosHash.AreEqualSlow(calculatedHmac, ciphertext, calculatedHmac.Length)) { throw new SecurityException("Invalid Checksum"); } var output = new byte[plaintext.Length - ConfounderSize]; Buffer.BlockCopy(plaintext, ConfounderSize, output, 0, output.Length); return(output); }
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())); }