public void WDigestHash_EncodeProperty() { byte[] blob = "3100011D00000000000000000000000038723ED34D6DF84FB88972CE00B9D28952E954B1F92368D40FB88C9B54DF2D5AE275AEEBE6D0A0DA7B0572F719BB307B38723ED34D6DF84FB88972CE00B9D28952E954B1F92368D40FB88C9B54DF2D5AFE93C6CC61028BDD93B74042ED778C2338723ED34D6DF84FB88972CE00B9D289429072BFFA5BE07598CA43AE52833732429072BFFA5BE07598CA43AE528337320749C5CCFC3FCD9A23F8EE373FE0DAEC55113516DFD326403029BBC568B2FA4A429072BFFA5BE07598CA43AE52833732D04622762DF13DB90786B72C423017DB55113516DFD326403029BBC568B2FA4AC35F5A94C1F7BD9C0B654DA4526F2DA5C35F5A94C1F7BD9C0B654DA4526F2DA59C200D20FA1D18F814BD491108E3F5440784E0DD92BED5304A4589BC6751DD8C148DC7BE0270C46539CBC9A6C3509E2691F52DC6ECBF3CF2B1D802EBD9E56319D09E4A62CCF638C2B8AD1360BEBD11CED09E4A62CCF638C2B8AD1360BEBD11CEDB565E643D18D2C3BB4F3DA942B27DDC56D0DA9761F9E1BD60332B365A10677256D0DA9761F9E1BD60332B365A1067725F8A9A18636D788F56C432A6E51FE884FBB9BB6939D39D22E17DCCFFBAB6F314FC31AFC0E0C72839C51F5647D1582B83AECD3707827166AE2D55DA8A4F2A8D8B".HexToBinary(); byte[][] hashes = WDigestHash.Parse(blob); byte[] newBlob = WDigestHash.Encode(hashes); Assert.AreEqual(blob.ToHex(), newBlob.ToHex()); }
private void ReadProperties(BinaryReader reader) { // The number of USER_PROPERTY elements in the UserProperties field. short propertyCount = reader.ReadInt16(); for (int i = 0; i < propertyCount; i++) { // The number of bytes, in little-endian byte order, of PropertyName. short nameLength = reader.ReadInt16(); // The number of bytes contained in PropertyValue. short valueLength = reader.ReadInt16(); // This value MUST be ignored by the recipient and MAY<21> be set to arbitrary values on update. short reserved = reader.ReadInt16(); // The name of this property as a UTF-16 encoded string. byte[] binaryPropertyName = reader.ReadBytes(nameLength); // The value of this property. The value MUST be hexadecimal-encoded using an 8-bit character size, and the values '0' through '9' inclusive and 'a' through 'f' inclusive (the specification of 'a' through 'f' is case-sensitive). byte[] binaryPropertyValue = reader.ReadBytes(valueLength); string propertyName = Encoding.Unicode.GetString(binaryPropertyName); string hexPropertyValue = Encoding.ASCII.GetString(binaryPropertyValue); byte[] decodedPropertyValue = hexPropertyValue.HexToBinary(); switch (propertyName) { case PropertyCleartext: // The cleartext password. this.ClearText = Encoding.Unicode.GetString(decodedPropertyValue); break; case PropertyKerberos: // Cryptographic hashes of the cleartext password for the Kerberos authentication protocol. this.Kerberos = new KerberosCredential(decodedPropertyValue); break; case PropertyKerberosNew: // Cryptographic hashes of the cleartext password for the Kerberos authentication protocol. this.KerberosNew = new KerberosCredentialNew(decodedPropertyValue); break; case PropertyWDigest: // Cryptographic hashes of the cleartext password for the Digest authentication protocol. this.WDigest = WDigestHash.Parse(decodedPropertyValue); break; case PropertyPackages: // A list of the credential types that are stored as properties in decryptedSecret. var packages = Encoding.Unicode.GetString(decodedPropertyValue).Split(Char.MinValue); break; case PropertyNTLMStrongHash: // This is a totally random value generated by DC on each password change, since Windows Server 2016. this.NTLMStrongHash = decodedPropertyValue; break; default: // Unknown package. This should never happen break; } } }