private static KerberosKey CreateKey() { var principalName = new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "CORP.IDENTITYINTERVENTION.COM", new[] { "testuser" }); var host = ""; var key = new KerberosKey("P@ssw0rd!", principalName: principalName, host: host, saltType: SaltType.ActiveDirectoryUser); return(key); }
public void ValidateChecksum(KerberosKey key) { var expected = GenerateChecksum(key, this.UserName, this.UserRealm, this.AuthPackage); if (!KerberosCryptoTransformer.AreEqualSlow(expected.Checksum.Span, this.Checksum.Checksum.Span)) { throw new SecurityException("Invalid checksum"); } }
public void KrbEncryptedDataFailsMismatchedDerivedKey() { var key = new KerberosKey(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, etype: EncryptionType.AES256_CTS_HMAC_SHA1_96); var encryptedData = KrbEncryptedData.Encrypt(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, key, KeyUsage.Ticket); var keyOther = new KerberosKey(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, etype: EncryptionType.AES128_CTS_HMAC_SHA1_96); encryptedData.Decrypt(keyOther, KeyUsage.Ticket, d => d); }
private KerberosAuthenticator CreateAuthenticator() { // This could be done with DI and a factory pattern, but we're keeping it simple here. var principalName = new PrincipalName(PrincipalNameType.NT_PRINCIPAL, Options.Domain, new[] { Options.UserName }); var key = new KerberosKey(Options.Password, principalName, Options.Password); var validator = new KerberosValidator(key); var authenticator = new KerberosAuthenticator(validator); return(authenticator); }
private static void AssertChecksum(string plaintextHex, string keyHex, string checksumHex, ChecksumType type) { var hmac = CryptoService.CreateChecksum(type, HexToByte(checksumHex), HexToByte(plaintextHex)); hmac.Usage = KeyUsage.Ticket; var key = new KerberosKey(HexToByte(keyHex)); hmac.Validate(key); }
private DecryptedKrbApReq DecryptApReq(KrbApReq apReq, KerberosKey krbtgtKey) { var apReqDecrypted = new DecryptedKrbApReq(apReq, MessageType.KRB_TGS_REQ); apReqDecrypted.Decrypt(krbtgtKey); apReqDecrypted.Validate(Validation); return(apReqDecrypted); }
internal void Sign(Memory <byte> pacUnsigned, KerberosKey key) { Validator = CryptoService.CreateChecksumValidator(Type, Signature, pacUnsigned.ToArray()); Validator.Sign(key); this.Signature = Validator.Signature.ToArray(); IsDirty = true; }
internal void Sign(Memory <byte> pacUnsigned, KerberosKey key) { Validator = CryptoService.CreateChecksumValidator(Type, Signature, pacUnsigned); Validator.Sign(key); Signature = MemoryMarshal.AsMemory(Validator.Signature); IsDirty = true; }
private static KrbEncTicketPart ExtractTgt(KrbTgsReq tgsReq) { var paData = tgsReq.PaData.First(p => p.Type == PaDataType.PA_TGS_REQ); var apReq = paData.DecodeApReq(); var krbtgtKey = new KerberosKey(key: Key, etype: EncryptionType.AES256_CTS_HMAC_SHA1_96); return(apReq.Ticket.EncryptedPart.Decrypt(krbtgtKey, KeyUsage.Ticket, b => new KrbEncTicketPart().DecodeAsApplication(b))); }
internal void Sign(Memory <byte> pacUnsigned, KerberosKey key) { this.Validator = CryptoService.CreateChecksum(this.Type, this.Signature, pacUnsigned); this.Validator.Sign(key); this.Signature = MemoryMarshal.AsMemory(this.Validator.Signature); this.IsDirty = true; }
private static void GenerateActiveDirectoryUserSalt(KerberosKey key, StringBuilder salt) { // User accounts: // // < DNS of the realm, converted to upper case> | < user name > // // Ex: REALM.COMusername salt.Append(key.PrincipalName.Realm.ToUpperInvariant()); salt.Append(key.PrincipalName.Names.First()); }
public void Validate(KerberosKey key) { if (this.Validator == null) { throw new InvalidOperationException($"Validator not set for checksum type {this.Type}"); } this.Validator.Validate(key); this.Validated = true; }
public static KrbEncryptedData Encrypt(ReadOnlyMemory <byte> data, KerberosKey key, KeyUsage usage) { var crypto = CryptoService.CreateTransform(key.EncryptionType); ReadOnlyMemory <byte> cipher = crypto.Encrypt(data, key, usage); return(new KrbEncryptedData { Cipher = cipher, EType = key.EncryptionType, KeyVersionNumber = key.Version }); }
public T Decrypt <T>(KerberosKey key, KeyUsage usage, Func <ReadOnlyMemory <byte>, T> func) { var crypto = CryptoService.CreateTransform(this.EType); if (crypto == null) { throw new InvalidOperationException($"CryptoService couldn't create a transform for type {key.EncryptionType}"); } var decrypted = crypto.Decrypt(this.Cipher, key, usage); return(func(decrypted)); }
public static string GenerateSalt(KerberosKey key) { if (!string.IsNullOrWhiteSpace(key.Salt)) { return(key.Salt); } var salt = new StringBuilder(); GenerateSalt(key, salt); return(salt.ToString()); }
public override ReadOnlyMemory <byte> String2Key(KerberosKey key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(this.String2Key( key.PasswordBytes, AesSalts.GenerateSalt(key), key.IterationParameter )); }
private ReadOnlyMemory <byte> GetOrDeriveKey(KerberosKey kerberosKey, KeyUsage usage) { if (kerberosKey == null) { throw new InvalidOperationException("Key cannot be null"); } return(kerberosKey.GetOrDeriveKey( this, $"{usage}|Ke|{KeySize}|{BlockSize}", key => DK(key, usage, KeyDerivationMode.Ke, KeySize, BlockSize) )); }
public void KerberosKeyIdMatches() { var key = KerberosKey.DeriveFromKeyId( "P@ssw0rd!", new Guid("0aa29dcb-3a9b-413f-aee2-8df91fd1118e"), KrbPrincipalName.FromString( "host/test.identityintervention.com", PrincipalNameType.NT_SRV_INST, "corp.identityintervention.com" ) ); AssertKeyMatchesGuid(key.EncryptionType, key); }
public void DecryptAsReqApplicationMessage() { var asReqBin = ReadDataFile("messages\\as-req-preauth").Skip(4).ToArray(); var asReq = KrbAsReq.DecodeApplication(asReqBin); Assert.IsNotNull(asReq); KerberosKey key = CreateKey(); var ts = asReq.DecryptTimestamp(key); Assert.AreEqual(636985444450060358L, ts.Ticks); }
public void ThrowsUnknownChecksumType() { var principal = new FakeKerberosPrincipal("*****@*****.**"); var pac = principal.GeneratePac(); var kdcKey = new KerberosKey(new byte[234], etype: (EncryptionType)(-1)); var serverKey = new KerberosKey(new byte[32], etype: EncryptionType.AES256_CTS_HMAC_SHA1_96); CryptoService.UnregisterChecksumAlgorithm((ChecksumType)(-1)); CryptoService.UnregisterCryptographicAlgorithm((EncryptionType)(-1)); pac.Encode(kdcKey, serverKey); }
private static void GenerateRfc4120Salt(KerberosKey key, StringBuilder salt) { // RFC 4120 section 4 // if none is provided via pre-authentication data, is the // concatenation of the principal's realm and name components, in order, // with no separators salt.Append(key.PrincipalName.Realm); foreach (var name in key.PrincipalName.Names) { salt.Append(name); } }
public void TestKerberosValidatorRC4ModifiedPac() { var key = ReadDataFile("rc4-key-data"); var kerbKey = new KerberosKey(key); var pacValidated = ValidatePac( kerbKey, Convert.FromBase64String(RC4_PAC_SIGNATURE), Convert.FromBase64String(RC4_PAC) ); Assert.IsTrue(pacValidated); GenerateCorruptPac(RC4_PAC_SIGNATURE, RC4_PAC).Validator.Validate(kerbKey); }
private static KerberosKey CreateKey() { var principalName = new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "CORP.IDENTITYINTERVENTION.COM", new[] { "testuser" }); var host = string.Empty; var key = new KerberosKey( "P@ssw0rd!", principalName: principalName, host: host, saltType: SaltType.ActiveDirectoryUser, etype: EncryptionType.AES256_CTS_HMAC_SHA1_96 ); return(key); }
private static async Task <IEnumerable <KrbAuthorizationData> > GenerateAuthorizationData( IKerberosPrincipal principal, KerberosKey krbtgt ) { // authorization-data is annoying because it's a sequence of // ad-if-relevant, which is a sequence of sequences // it ends up looking something like // // [ // { // Type = ad-if-relevant, // Data = // [ // { // Type = pac, // Data = encoded-pac // }, // ... // ], // }, // ... // ] var pac = await principal.GeneratePac(); var authz = new List <KrbAuthorizationData>(); var sequence = new KrbAuthorizationDataSequence { AuthorizationData = new[] { new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = pac.Encode(krbtgt, krbtgt) } } }; authz.Add(new KrbAuthorizationData { Type = AuthorizationDataType.AdIfRelevant, Data = sequence.Encode().AsMemory() }); return(authz); }
public void KerberosValidatorAes128ModifiedPac() { var key = ReadDataFile("aes128-key-data"); var kerbKey = new KerberosKey(key); var pacValidated = ValidatePac( kerbKey, Convert.FromBase64String(AES128_PAC_SIGNATURE), Convert.FromBase64String(AES128_PAC) ); Assert.IsTrue(pacValidated); GenerateCorruptPac(AES128_PAC_SIGNATURE, AES128_PAC).Validator.Validate(kerbKey); }
public async Task TestPacRoundtrip() { var keyBytes = ReadDataFile("rc4-key-data"); var key = new KerberosKey(keyBytes, etype: EncryptionType.RC4_HMAC_NT); var pac = await GeneratePac(); var encoded = pac.Encode(key, key); var pacDecoded = new PrivilegedAttributeCertificate(encoded.ToArray()); ; pacDecoded.ServerSignature.Validator.Validate(key); pacDecoded.KdcSignature.Validator.Validate(key); }
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)); }
public override ReadOnlyMemory <byte> MakeChecksum( ReadOnlyMemory <byte> data, KerberosKey key, KeyUsage usage, KeyDerivationMode kdf, int hashSize ) { var ki = key.GetOrDeriveKey( this, $"{usage}|{kdf}|{KeySize}|{BlockSize}", k => DK(k, usage, kdf, KeySize, BlockSize) ); return(Hmac(ki, data).Slice(0, hashSize)); }
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 void TgsParse() { var tgsReqBytes = ReadDataFile("messages\\tgs-req-testuser-host-app03").Skip(4).ToArray(); var tgsReq = KrbTgsReq.DecodeApplication(tgsReqBytes); var paData = tgsReq.PaData.First(p => p.Type == PaDataType.PA_TGS_REQ); var apReq = paData.DecodeApReq(); var krbtgtKey = new KerberosKey(key: key); var krbtgt = apReq.Ticket.EncryptedPart.Decrypt(krbtgtKey, KeyUsage.Ticket, b => new KrbEncTicketPart().DecodeAsApplication(b)); Assert.AreEqual("testuser", krbtgt.CName.FullyQualifiedName); }