ntlm.java

来自「Light in the box 抓取程序。 使用HttpClient」· Java 代码 · 共 566 行 · 第 1/2 页

JAVA
566 行
字号
        // Host offset (always 32).        byte[] hostOff = convertShort(32);        addByte(hostOff[0]);        addByte(hostOff[1]);        addByte((byte) 0);        addByte((byte) 0);        // Host String.        addBytes(hostBytes);        // Domain String.        addBytes(domainBytes);        return getResponse();    }    /**      * Extracts the server nonce out of the given message type 2.     *      * @param message the String containing the base64 encoded message.     * @return an array of 8 bytes that the server sent to be used when     * hashing the password.     */    public byte[] parseType2Message(String message) {        // Decode the message first.        byte[] msg = Base64.decodeBase64(EncodingUtil.getBytes(message, DEFAULT_CHARSET));        byte[] nonce = new byte[8];        // The nonce is the 8 bytes starting from the byte in position 24.        for (int i = 0; i < 8; i++) {            nonce[i] = msg[i + 24];        }        return nonce;    }    /**      * Creates the type 3 message using the given server nonce.  The type 3 message includes all the     * information for authentication, host, domain, username and the result of encrypting the     * nonce sent by the server using the user's password as the key.     *     * @param user The user name.  This should not include the domain name.     * @param password The password.     * @param host The host that is originating the authentication request.     * @param domain The domain to authenticate within.     * @param nonce the 8 byte array the server sent.     * @return The type 3 message.     * @throws AuthenticationException If {@encrypt(byte[],byte[])} fails.     */    public String getType3Message(String user, String password,            String host, String domain, byte[] nonce)    throws AuthenticationException {        int ntRespLen = 0;        int lmRespLen = 24;        domain = domain.toUpperCase();        host = host.toUpperCase();        user = user.toUpperCase();        byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET);        byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET);        byte[] userBytes = EncodingUtil.getBytes(user, credentialCharset);        int domainLen = domainBytes.length;        int hostLen = hostBytes.length;        int userLen = userBytes.length;        int finalLength = 64 + ntRespLen + lmRespLen + domainLen             + userLen + hostLen;        prepareResponse(finalLength);        byte[] ntlmssp = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET);        addBytes(ntlmssp);        addByte((byte) 0);        addByte((byte) 3);        addByte((byte) 0);        addByte((byte) 0);        addByte((byte) 0);        // LM Resp Length (twice)        addBytes(convertShort(24));        addBytes(convertShort(24));        // LM Resp Offset        addBytes(convertShort(finalLength - 24));        addByte((byte) 0);        addByte((byte) 0);        // NT Resp Length (twice)        addBytes(convertShort(0));        addBytes(convertShort(0));        // NT Resp Offset        addBytes(convertShort(finalLength));        addByte((byte) 0);        addByte((byte) 0);        // Domain length (twice)        addBytes(convertShort(domainLen));        addBytes(convertShort(domainLen));                // Domain offset.        addBytes(convertShort(64));        addByte((byte) 0);        addByte((byte) 0);        // User Length (twice)        addBytes(convertShort(userLen));        addBytes(convertShort(userLen));        // User offset        addBytes(convertShort(64 + domainLen));        addByte((byte) 0);        addByte((byte) 0);        // Host length (twice)        addBytes(convertShort(hostLen));        addBytes(convertShort(hostLen));        // Host offset        addBytes(convertShort(64 + domainLen + userLen));        for (int i = 0; i < 6; i++) {            addByte((byte) 0);        }        // Message length        addBytes(convertShort(finalLength));        addByte((byte) 0);        addByte((byte) 0);        // Flags        addByte((byte) 6);        addByte((byte) 82);        addByte((byte) 0);        addByte((byte) 0);        addBytes(domainBytes);        addBytes(userBytes);        addBytes(hostBytes);        addBytes(hashPassword(password, nonce));        return getResponse();    }    /**      * Creates the LANManager and NT response for the given password using the     * given nonce.     * @param password the password to create a hash for.     * @param nonce the nonce sent by the server.     * @return The response.     * @throws HttpException If {@link #encrypt(byte[],byte[])} fails.     */    private byte[] hashPassword(String password, byte[] nonce)        throws AuthenticationException {        byte[] passw = EncodingUtil.getBytes(password.toUpperCase(), credentialCharset);        byte[] lmPw1 = new byte[7];        byte[] lmPw2 = new byte[7];        int len = passw.length;        if (len > 7) {            len = 7;        }        int idx;        for (idx = 0; idx < len; idx++) {            lmPw1[idx] = passw[idx];        }        for (; idx < 7; idx++) {            lmPw1[idx] = (byte) 0;        }        len = passw.length;        if (len > 14) {            len = 14;        }        for (idx = 7; idx < len; idx++) {            lmPw2[idx - 7] = passw[idx];        }        for (; idx < 14; idx++) {            lmPw2[idx - 7] = (byte) 0;        }        // Create LanManager hashed Password        byte[] magic = {            (byte) 0x4B, (byte) 0x47, (byte) 0x53, (byte) 0x21,             (byte) 0x40, (byte) 0x23, (byte) 0x24, (byte) 0x25        };        byte[] lmHpw1;        lmHpw1 = encrypt(lmPw1, magic);        byte[] lmHpw2 = encrypt(lmPw2, magic);        byte[] lmHpw = new byte[21];        for (int i = 0; i < lmHpw1.length; i++) {            lmHpw[i] = lmHpw1[i];        }        for (int i = 0; i < lmHpw2.length; i++) {            lmHpw[i + 8] = lmHpw2[i];        }        for (int i = 0; i < 5; i++) {            lmHpw[i + 16] = (byte) 0;        }        // Create the responses.        byte[] lmResp = new byte[24];        calcResp(lmHpw, nonce, lmResp);        return lmResp;    }    /**      * Takes a 21 byte array and treats it as 3 56-bit DES keys.  The 8 byte     * plaintext is encrypted with each key and the resulting 24 bytes are     * stored in the results array.     *      * @param keys The keys.     * @param plaintext The plain text to encrypt.     * @param results Where the results are stored.     * @throws AuthenticationException If {@link #encrypt(byte[],byte[])} fails.     */    private void calcResp(byte[] keys, byte[] plaintext, byte[] results)        throws AuthenticationException {        byte[] keys1 = new byte[7];        byte[] keys2 = new byte[7];        byte[] keys3 = new byte[7];        for (int i = 0; i < 7; i++) {            keys1[i] = keys[i];        }        for (int i = 0; i < 7; i++) {            keys2[i] = keys[i + 7];        }        for (int i = 0; i < 7; i++) {            keys3[i] = keys[i + 14];        }        byte[] results1 = encrypt(keys1, plaintext);        byte[] results2 = encrypt(keys2, plaintext);        byte[] results3 = encrypt(keys3, plaintext);        for (int i = 0; i < 8; i++) {            results[i] = results1[i];        }        for (int i = 0; i < 8; i++) {            results[i + 8] = results2[i];        }        for (int i = 0; i < 8; i++) {            results[i + 16] = results3[i];        }    }    /**      * Converts a given number to a two byte array in little endian order.     * @param num the number to convert.     * @return The byte representation of <i>num</i> in little endian order.     */    private byte[] convertShort(int num) {        byte[] val = new byte[2];        String hex = Integer.toString(num, 16);        while (hex.length() < 4) {            hex = "0" + hex;        }        String low = hex.substring(2, 4);        String high = hex.substring(0, 2);        val[0] = (byte) Integer.parseInt(low, 16);        val[1] = (byte) Integer.parseInt(high, 16);        return val;    }        /**     * @return Returns the credentialCharset.     */    public String getCredentialCharset() {        return credentialCharset;    }    /**     * @param credentialCharset The credentialCharset to set.     */    public void setCredentialCharset(String credentialCharset) {        this.credentialCharset = credentialCharset;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?