⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntlm.java

📁 真正的网络爬虫的源代码啊,希望大家好好阅读,写出心得体会啊
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
      //Gets the first 14-bytes of the ASCII upper cased password
      int len = password.length();
      if(len > 14)
        len = 14;
      Cipher c = Cipher.getInstance("DES/ECB/NoPadding");

      byte[] lm_pw = new byte[14];
      byte[] bytes = password.toUpperCase().getBytes();
      int i;
      for(i = 0; i < len; i++)
        lm_pw[i] = bytes[i];
      for(; i < 14; i++)
        lm_pw[i] = 0;

      byte[] lm_hpw = new byte[16];
      //Builds a first DES key with its first 7 bytes
      Key k = computeDESKey(lm_pw, 0);
      c.init(Cipher.ENCRYPT_MODE, k);
      //Hashes the MAGIC number with this key into the first 8 bytes of the result
      c.doFinal(MAGIC, 0, 8, lm_hpw, 0);

      //Repeats the work with the last 7 bytes to gets the last 8 bytes of the result
      k = computeDESKey(lm_pw, 7);
      c.init(Cipher.ENCRYPT_MODE, k);
      c.doFinal(MAGIC, 0, 8, lm_hpw, 8);

      return lm_hpw;
    } catch(InvalidKeySpecException ex) {
      return null;
    } catch(InvalidKeyException ex) {
      return null;
    } catch(BadPaddingException ex) {
      return null;
    } catch(IllegalBlockSizeException ex) {
      return null;
    } catch(ShortBufferException ex) {
      return null;
    }
  }

  /**
   * Computes the NT hashed version of a password.
   *
   * @param password the user password
   *
   * @return the NT hashed version of the password in a 16-bytes array
   *
   * @exception IllegalArgumentException if the supplied password is null
   * @exception NoSuchAlgorithmException if there isn't any suitable cipher algorithm
   */
  public static byte[] computeNTPassword(String password) throws IllegalArgumentException, NoSuchAlgorithmException {
    if(password == null)
      throw new IllegalArgumentException("password : null value not allowed");
    //Gets the first 14-bytes of the UNICODE password
    int len = password.length();
    if(len > 14)
      len = 14;
    byte[] nt_pw = new byte[2 * len];
    for(int i = 0; i < len; i++) {
        char ch = password.charAt(i);
        nt_pw[2 * i] = getLoByte(ch);
        nt_pw[2 * i + 1] = getHiByte(ch);
    }

    //Return its MD4 digest as the hashed version
    MessageDigest md = MessageDigest.getInstance("MD4");
    return md.digest(nt_pw);
  }
  /**
   * <p>
   * Computes the NTLM response to the nonce based on the supplied hashed passwords.
   * </p>
   * <p>
   * If the hashed password are not available they can be computed from the cleartext password
   * by the means of {@link #computeLMPassword(String) computeLMPassword} and
   * {@link #computeNTPassword(String) computeNTPassword} methods.
   * </p>
   *
   * @param lmPassword a 16-bytes array containing the Lan Manager hashed password
   * @param ntPassword a 16-bytes array containing the Lan Manager hashed password
   * @param nonce a 8-bytes array representing the server's nonce
   * @param lmResponse a 24-bytes array that will contain the Lan Manager response after the method invocation
   * @param ntResponse a 24-bytes array that will contain the NT response after the method invocation
   *
   * @exception IllegalArgumentException if a parameter has an illegal size
   * @exception javax.crypto.NoSuchPaddingException if there isn't any suitable padding method
   * @exception NoSuchAlgorithmException if there isn't any suitable cipher algorithm
   */
  public static void computeNTLMResponse(byte[] lmPassword, byte[] ntPassword, byte[] nonce, byte[] lmResponse, byte[] ntResponse) throws IllegalArgumentException, NoSuchPaddingException, NoSuchAlgorithmException {
    if(lmPassword.length != 16)
      throw new IllegalArgumentException("lmPassword : illegal size");
    if(ntPassword.length != 16)
      throw new IllegalArgumentException("ntPassword : illegal size");
    if(nonce.length != 8)
      throw new IllegalArgumentException("nonce : illegal size");
    if(lmResponse.length != 24)
      throw new IllegalArgumentException("lmResponse : illegal size");
    if(ntResponse.length != 24)
      throw new IllegalArgumentException("ntResponse : illegal size");
    try {
      //Puts the hashed passwords into 21-bytes arrays with trailing 0s
      byte[] lmHPw = new byte[21];
      byte[] ntHPw = new byte[21];
      System.arraycopy(lmPassword, 0, lmHPw, 0, 16);
      System.arraycopy(ntPassword, 0, ntHPw, 0, 16);
      for(int i = 16; i < 21; i++) {
        lmHPw[i] = 0;
        ntHPw[i] = 0;
      }
      //Encrypts the nonce with the padded hashed passwords to compute the responses
      System.arraycopy(encrypt(lmHPw, nonce), 0, lmResponse, 0, 24);
      System.arraycopy(encrypt(ntHPw, nonce), 0, ntResponse, 0, 24);
    } catch(ShortBufferException ex) {
    } catch(IllegalBlockSizeException ex) {
    } catch(BadPaddingException ex) {
    } catch(InvalidKeySpecException ex) {
    } catch(InvalidKeyException ex) {
    }
  }

  /**
   * <p>
   * Builds a request message for the host of the specified domain that can be send
   * to the server to start the NTLM protocol.
   * </p>
   * <p>
   * The returned message should be encoded according to protocol specific rules
   * (e.g. base 64 encoding).<br>
   * The message format is discussed <a href="http://www.innovation.ch/java/ntlm.html">here</a>.
   * </p>
   *
   * @param host the name of the host that is authenticating
   * @param hostDomain the name of the domain to which the host belongs
   *
   * @return the request message to send to server to open an authentication procedure
   *
   * @exception IOException if an error occurs during the message formatting
   *
   * @see <a href="http://www.innovation.ch/java/ntlm.html">NTLM Authentication Scheme for HTTP</a>
   *
   */
  public static byte[] formatRequest(String host, String hostDomain) throws IOException {
    hostDomain = hostDomain.toUpperCase();
    host = host.toUpperCase();
    short domainLen = (short)hostDomain.length();
    short hostLen = (short)host.length();
    short hostOff = 0x20;
    short domainOff = (short)(hostOff + hostLen);
    ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
    DataOutputStream dataOut = new DataOutputStream(os);
    dataOut.writeBytes("NTLMSSP\0");
    dataOut.writeByte(0x01);
    dataOut.writeByte(0x00);
    dataOut.writeByte(0x00);
    dataOut.writeByte(0x00);
    dataOut.writeShort(swapBytes((short)0xb203));
    dataOut.writeShort(0x0000);
    dataOut.writeShort(swapBytes(domainLen));
    dataOut.writeShort(swapBytes(domainLen));
    dataOut.writeShort(swapBytes(domainOff));
    dataOut.writeShort(0x0000);
    dataOut.writeShort(swapBytes(hostLen));
    dataOut.writeShort(swapBytes(hostLen));
    dataOut.writeShort(swapBytes(hostOff));
    dataOut.writeShort(0x0000);
    dataOut.write(host.getBytes());
    dataOut.write(hostDomain.getBytes());
    dataOut.flush();
    return os.toByteArray();
  }

  /**
   * <p>
   * Extracts from the server challenge response the nonce required to perform
   * the authentication.
   * </p>
   * <p>
   * The received message should be decoded according to protocol specific rules
   * (e.g. base 64 encoding).<br>
   * The message format is discussed <a href="http://www.innovation.ch/java/ntlm.html">here</a>.
   * </p>
   *
   * @param msg a byte array containing the server challenge message
   *
   * @exception IllegalArgumentException if a parameter has an illegal size
   *
   * @see <a href="http://www.innovation.ch/java/ntlm.html">NTLM Authentication Scheme for HTTP</a>
   */
  public static byte[] getNonce(byte[] msg) throws IllegalArgumentException {
    if(msg.length < 32)
      throw new IllegalArgumentException("msg : illegal size");
    byte[] nonce = new byte[8];
    System.arraycopy(msg, 24, nonce, 0, 8);
    return nonce;
  }

  /**
   * <p>
   * Builds the nonce response message.
   * </p>
   * <p>It requires the Lan Manager and NT hashed
   * version of user password, that can be computed from the cleartext version by
   * {@link #computeNTPassword(String) computeNTPassword} and
   * {@link #computeNTLMResponse(byte[], byte[], byte[], byte[], byte[]) computeNTLMResponse},
   * and the nonce obtained from the server by {@link #getNonce(byte[]) getNonce}.<br>
   * The returned message should be encoded according to protocol specific rules
   * (e.g. base 64 encoding).<br>
   * The message format is discussed <a href="http://www.innovation.ch/java/ntlm.html">here</a>.
   * </p>
   *
   * @param host the name of the host that is authenticating
   * @param user the name of the user
   * @param userDomain the name of the domain to which the user belongs
   * @param lmPassword a 16-bytes array containing the Lan Manager hashed password
   * @param ntPassword a 16-bytes array containing the NT hashed password
   * @param nonce a 8-byte array containing the nonce sent by server to reply to the request message
   *
   * @return the challenge response message to send to server to complete the authentication procedure
   *
   * @exception IOException if an error occurs during the message formatting
   * @exception IllegalArgumentException if a parameter has an illegal size
   * @exception javax.crypto.NoSuchPaddingException if there isn't any suitable padding method
   * @exception NoSuchAlgorithmException if there isn't any suitable cipher algorithm
   *
   * @see <a href="http://www.innovation.ch/java/ntlm.html">NTLM Authentication Scheme for HTTP</a>
   */
  public static byte[] formatResponse(String host, String user, String userDomain, byte[] lmPassword, byte[] ntPassword, byte[] nonce) throws IllegalArgumentException, IOException, NoSuchAlgorithmException, NoSuchPaddingException {
    if(host == null)
      throw new IllegalArgumentException("host : null value not allowed");
    if(user == null)
      throw new IllegalArgumentException("user : null value not allowed");
    if(userDomain == null)
      throw new IllegalArgumentException("userDomain : null value not allowed");
    if(lmPassword == null)
      throw new IllegalArgumentException("lmPassword : null value not allowed");
    if(ntPassword == null)
      throw new IllegalArgumentException("ntPassword : null value not allowed");
    if(nonce == null)
      throw new IllegalArgumentException("nonce : null value not allowed");
    if(lmPassword.length != 16)
      throw new IllegalArgumentException("lmPassword : illegal size");
    if(ntPassword.length != 16)
      throw new IllegalArgumentException("ntPassword : illegal size");
    if(nonce.length != 8)
      throw new IllegalArgumentException("nonce : illegal size");

    byte[] lmResponse = new byte[24];
    byte[] ntResponse = new byte[24];

    computeNTLMResponse(lmPassword, ntPassword, nonce, lmResponse, ntResponse);

    userDomain = userDomain.toUpperCase();
    host = host.toUpperCase();
    short lmRespLen = (short)0x18;
    short ntRespLen = (short)0x18;
    short domainLen = (short)(2 * userDomain.length());
    short hostLen = (short)(2 * host.length());
    short userLen = (short)(2 * user.length());
    short domainOff = (short)0x40;
    short userOff = (short)(domainOff + domainLen);
    short hostOff = (short)(userOff + userLen);
    short lmRespOff = (short)(hostOff + hostLen);
    short ntRespOff = (short)(lmRespOff + lmRespLen);
    short msgLen = (short)(ntRespOff + ntRespLen);
    ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
    DataOutputStream dataOut = new DataOutputStream(os);
    dataOut.writeBytes("NTLMSSP\0");
    dataOut.writeByte(0x03);
    dataOut.writeByte(0x00);
    dataOut.writeByte(0x00);
    dataOut.writeByte(0x00);
    dataOut.writeShort(swapBytes(lmRespLen));
    dataOut.writeShort(swapBytes(lmRespLen));
    dataOut.writeShort(swapBytes(lmRespOff));
    dataOut.writeShort(0x0000);
    dataOut.writeShort(swapBytes(ntRespLen));
    dataOut.writeShort(swapBytes(ntRespLen));
    dataOut.writeShort(swapBytes(ntRespOff));
    dataOut.writeShort(0x0000);
    dataOut.writeShort(swapBytes(domainLen));
    dataOut.writeShort(swapBytes(domainLen));
    dataOut.writeShort(swapBytes(domainOff));
    dataOut.writeShort(0x0000);
    dataOut.writeShort(swapBytes(userLen));
    dataOut.writeShort(swapBytes(userLen));
    dataOut.writeShort(swapBytes(userOff));
    dataOut.writeShort(0x0000);
    dataOut.writeShort(swapBytes(hostLen));
    dataOut.writeShort(swapBytes(hostLen));
    dataOut.writeShort(swapBytes(hostOff));
    dataOut.writeShort(0x0000);
    dataOut.writeInt(0x00000000);
    dataOut.writeShort(swapBytes(msgLen));
    dataOut.writeShort(0x0000);
    dataOut.writeShort(0x0000);  //    dataOut.writeShort(swapBytes((short)0x8201));
    dataOut.writeShort(0x0000);

    for(int i = 0; i < userDomain.length(); i++)
      dataOut.writeShort(swapBytes((short)userDomain.charAt(i)));
    for(int i = 0; i < user.length(); i++)
      dataOut.writeShort(swapBytes((short)user.charAt(i)));
    for(int i = 0; i < host.length(); i++)
      dataOut.writeShort(swapBytes((short)host.charAt(i)));
    dataOut.write(lmResponse);
    dataOut.write(ntResponse);
    dataOut.flush();
    return os.toByteArray();
  }
}

⌨️ 快捷键说明

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