ntlmpasswordauthentication.java
来自「java ftp 操作代码,程序可以直接运行」· Java 代码 · 共 445 行 · 第 1/2 页
JAVA
445 行
initDefaults();
if( domain == null ) this.domain = DEFAULT_DOMAIN;
if( username == null ) this.username = DEFAULT_USERNAME;
if( password == null ) this.password = DEFAULT_PASSWORD;
}
/**
* Create an <tt>NtlmPasswordAuthentication</tt> object with raw password
* hashes. This is used exclusively by the <tt>jcifs.http.NtlmSsp</tt>
* class which is in turn used by NTLM HTTP authentication functionality.
*/
public NtlmPasswordAuthentication( String domain, String username,
byte[] challenge, byte[] ansiHash, byte[] unicodeHash ) {
if( domain == null || username == null ||
ansiHash == null || unicodeHash == null ) {
throw new IllegalArgumentException( "External credentials cannot be null" );
}
this.domain = domain;
this.username = username;
this.password = null;
this.challenge = challenge;
this.ansiHash = ansiHash;
this.unicodeHash = unicodeHash;
hashesExternal = true;
}
/**
* Returns the domain.
*/
public String getDomain() {
return domain;
}
/**
* Returns the username.
*/
public String getUsername() {
return username;
}
/**
* Returns the password in plain text or <tt>null</tt> if the raw password
* hashes were used to construct this <tt>NtlmPasswordAuthentication</tt>
* object which will be the case when NTLM HTTP Authentication is
* used. There is no way to retrieve a users password in plain text unless
* it is supplied by the user at runtime.
*/
public String getPassword() {
return password;
}
/**
* Return the domain and username in the format:
* <tt>domain\\username</tt>. This is equivalent to <tt>toString()</tt>.
*/
public String getName() {
boolean d = domain.length() > 0 && domain.equals( "?" ) == false;
return d ? domain + "\\" + username : username;
}
/**
* Computes the 24 byte ANSI password hash given the 8 byte server challenge.
*/
public byte[] getAnsiHash( byte[] challenge ) {
if( hashesExternal ) {
return ansiHash;
}
switch (LM_COMPATIBILITY) {
case 0:
case 1:
return getPreNTLMResponse( password, challenge );
case 2:
return getNTLMResponse( password, challenge );
case 3:
case 4:
case 5:
if( clientChallenge == null ) {
clientChallenge = new byte[8];
RANDOM.nextBytes( clientChallenge );
}
return getLMv2Response(domain, username, password, challenge,
clientChallenge);
default:
return getPreNTLMResponse( password, challenge );
}
}
/**
* Computes the 24 byte Unicode password hash given the 8 byte server challenge.
*/
public byte[] getUnicodeHash( byte[] challenge ) {
if( hashesExternal ) {
return unicodeHash;
}
switch (LM_COMPATIBILITY) {
case 0:
case 1:
case 2:
return getNTLMResponse( password, challenge );
case 3:
case 4:
case 5:
/*
if( clientChallenge == null ) {
clientChallenge = new byte[8];
RANDOM.nextBytes( clientChallenge );
}
return getNTLMv2Response(domain, username, password, null,
challenge, clientChallenge);
*/
return new byte[0];
default:
return getNTLMResponse( password, challenge );
}
}
/**
* Returns the effective user session key.
*
* @param challenge The server challenge.
* @return A <code>byte[]</code> containing the effective user session key,
* used in SMB MAC signing and NTLMSSP signing and sealing.
*/
public byte[] getUserSessionKey(byte[] challenge) {
if (hashesExternal) return null;
byte[] key = new byte[16];
try {
getUserSessionKey(challenge, key, 0);
} catch (Exception ex) {
if( log.level > 0 )
ex.printStackTrace( log );
}
return key;
}
/**
* Calculates the effective user session key.
*
* @param challenge The server challenge.
* @param dest The destination array in which the user session key will be
* placed.
* @param offset The offset in the destination array at which the
* session key will start.
*/
void getUserSessionKey(byte[] challenge, byte[] dest, int offset)
throws Exception {
if (hashesExternal) return;
MD4 md4 = new MD4();
md4.update(password.getBytes("UnicodeLittleUnmarked"));
switch (LM_COMPATIBILITY) {
case 0:
case 1:
case 2:
md4.update(md4.digest());
md4.digest(dest, offset, 16);
break;
case 3:
case 4:
case 5:
if( clientChallenge == null ) {
clientChallenge = new byte[8];
RANDOM.nextBytes( clientChallenge );
}
HMACT64 hmac = new HMACT64(md4.digest());
hmac.update(username.toUpperCase().getBytes(
"UnicodeLittleUnmarked"));
hmac.update(domain.toUpperCase().getBytes(
"UnicodeLittleUnmarked"));
byte[] ntlmv2Hash = hmac.digest();
hmac = new HMACT64(ntlmv2Hash);
hmac.update(challenge);
hmac.update(clientChallenge);
HMACT64 userKey = new HMACT64(ntlmv2Hash);
userKey.update(hmac.digest());
userKey.digest(dest, offset, 16);
break;
default:
md4.update(md4.digest());
md4.digest(dest, offset, 16);
break;
}
}
/**
* Compares two <tt>NtlmPasswordAuthentication</tt> objects for
* equality. Two <tt>NtlmPasswordAuthentication</tt> objects are equal if
* their caseless domain and username fields are equal and either both hashes are external and they are equal or both internally supplied passwords are equal. If one <tt>NtlmPasswordAuthentication</tt> object has external hashes (meaning negotiated via NTLM HTTP Authentication) and the other does not they will not be equal. This is technically not correct however the server 8 byte challage would be required to compute and compare the password hashes but that it not available with this method.
*/
public boolean equals( Object obj ) {
if( obj instanceof NtlmPasswordAuthentication ) {
NtlmPasswordAuthentication ntlm = (NtlmPasswordAuthentication)obj;
if( ntlm.domain.toUpperCase().equals( domain.toUpperCase() ) &&
ntlm.username.toUpperCase().equals( username.toUpperCase() )) {
if( hashesExternal && ntlm.hashesExternal ) {
return Arrays.equals( ansiHash, ntlm.ansiHash ) &&
Arrays.equals( unicodeHash, ntlm.unicodeHash );
/* This still isn't quite right. If one npa object does not have external
* hashes and the other does then they will not be considered equal even
* though they may be.
*/
} else if( !hashesExternal && password.equals( ntlm.password )) {
return true;
}
}
}
return false;
}
/**
* Return the upcased username hash code.
*/
public int hashCode() {
return getName().toUpperCase().hashCode();
}
/**
* Return the domain and username in the format:
* <tt>domain\\username</tt>. This is equivalent to <tt>getName()</tt>.
*/
public String toString() {
return getName();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?