/// <summary>
        /// Validate the NT hash of the new password (as presented by the client) encrypted according to the
        /// specification of ENCRYPTED_NT_OWF_PASSWORD where the key is the 16-byte SMB session key established by
        /// the underlying authentication protocol(either Kerberos or NTLM).
        /// </summary>
        /// <param name="sessionKey">The session key used for encryption.</param>
        /// <param name="target"> the target to be validate</param>
        /// <returns>validate result</returns>
        public bool ValidateNewNtOwfPasswordEncryptedWithSessionKey(byte[] sessionKey, _ENCRYPTED_LM_OWF_PASSWORD target)
        {
            _ENCRYPTED_LM_OWF_PASSWORD expected = GetNewNtOwfPasswordEncryptedWithSessionKey(sessionKey);
            bool isSame = ObjectUtility.DeepCompare(expected, target);

            return(isSame);
        }
        public bool ValidateEncryptedNtOwfPasswordWithUserId(uint userId, _ENCRYPTED_LM_OWF_PASSWORD target)
        {
            _ENCRYPTED_LM_OWF_PASSWORD expected = GetEncryptedNtOwfPasswordWithUserId(userId);
            bool isSame = ObjectUtility.DeepCompare(expected, target);

            return(isSame);
        }
        public bool ValidateNewNtEncryptedWithNewLm(_ENCRYPTED_LM_OWF_PASSWORD target)
        {
            _ENCRYPTED_LM_OWF_PASSWORD expected = GetNewNtEncryptedWithNewLm();
            bool isSame = ObjectUtility.DeepCompare(expected, target);

            return(isSame);
        }
        public bool ValidateOldLmOwfPasswordEncryptedWithNewNt(_ENCRYPTED_LM_OWF_PASSWORD target)
        {
            _ENCRYPTED_LM_OWF_PASSWORD expected = GetOldLmOwfPasswordEncryptedWithNewNt();
            bool isSame = ObjectUtility.DeepCompare(expected, target);

            return(isSame);
        }
        /// <summary>
        /// Splits both the block and the key to 2 halves, then transforms the keys, and encrypts the blocks
        /// with the transformed keys
        /// </summary>
        /// <param name="block">The input block to be encrypted</param>
        /// <param name="key">The encryption key</param>
        /// <returns>The encrypted data</returns>
        public static _ENCRYPTED_LM_OWF_PASSWORD EncryptBlockWithKey(byte[] block, byte[] key)
        {
            // The block size for DES ECB encryption
            const int samrEncryptionBlockSize = 8;

            _ENCRYPTED_LM_OWF_PASSWORD encryptedPwd = new _ENCRYPTED_LM_OWF_PASSWORD();

            byte[] block1 = null;
            byte[] block2 = null;
            byte[] key1   = null;
            byte[] key2   = null;

            // Split blocks into 2 blocks with each has the length samrEncryptionBlockSize
            SplitBlock(block, samrEncryptionBlockSize, samrEncryptionBlockSize, out block1, out block2);
            // Split keys into 2 underivedKeySize size blocks
            SplitBlock(key, underivedKeySize, underivedKeySize, out key1, out key2);

            // Derive keys
            byte[] transformedKey1 = TransformKey(key1);
            byte[] transformedKey2 = TransformKey(key2);

            // Do encryption
            byte[] encryptedBlock1 = DesEcbEncrypt(block1, transformedKey1);
            byte[] encryptedBlock2 = DesEcbEncrypt(block2, transformedKey2);
            // Concatenate the encrypted blocks
            encryptedPwd.data = MergeBlocks(encryptedBlock1, encryptedBlock2);

            return(encryptedPwd);
        }