Click here to Skip to main content
15,884,099 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
package net.sf.jradius.util;

import gnu.crypto.cipher.CipherFactory;
import gnu.crypto.cipher.IBlockCipher;
import gnu.crypto.cipher.WeakKeyException;
import gnu.crypto.hash.HashFactory;
import gnu.crypto.hash.IMessageDigest;

import java.util.HashMap;
import java.util.Map;

/**
* MSCHAP implementation translated into Java from the original
* pseudocode can be found in RFC 2759 and 2433.
*
* @author David Bird
*/
public final class MSCHAP
{
private static void parity_key(byte[] szOut, final byte[] szIn, final int offset)
{
int i;
int cNext = 0;
int cWorking = 0;

for (i = 0; i < 7; i++)
{
cWorking = 0xFF & szIn[i + offset];
szOut[i] = (byte)(((cWorking >> i) | cNext | 1) & 0xff);
cWorking = 0xFF & szIn[i + offset];
cNext = ((cWorking << (7 - i)));
}

szOut[i] = (byte) (cNext | 1);
}

private static byte[] unicode(byte[] in)
{
byte b[] = new byte[in.length * 2];
for (int i = 0; i < b.length; i++)
b[i] = 0;
for (int i = 0; i < in.length; i++)
b[(2 * i)] = in[i];
return b;
}

private static byte[] ChallengeHash(final byte[] PeerChallenge, final byte[] AuthenticatorChallenge, final byte[] UserName)
{
byte Challenge[] = new byte[8];
IMessageDigest md = HashFactory.getInstance("SHA-1");
md.update(PeerChallenge, 0, 16);
md.update(AuthenticatorChallenge, 0, 16);
md.update(UserName, 0, UserName.length);
System.arraycopy(md.digest(), 0, Challenge, 0, 8);
return Challenge;
}

private static byte[] NtPasswordHash(byte[] Password)
{
byte PasswordHash[] = new byte[16];
byte uniPassword[] = unicode(Password);
IMessageDigest md = HashFactory.getInstance("MD4");
md.update(uniPassword, 0, uniPassword.length);
System.arraycopy(md.digest(), 0, PasswordHash, 0, 16);
return PasswordHash;
}

/* not used currently
private static byte[] HashNtPasswordHash(byte[] PasswordHash)
{
byte PasswordHashHash[] = new byte[16];
IMessageDigest md = HashFactory.getInstance("MD4");
md.update(PasswordHash, 0, 16);
System.arraycopy(md.digest(), 0, PasswordHashHash, 0, 16);
return PasswordHashHash;
}
*/

private static void DesEncrypt(byte[] Clear, int clearOffset, byte[] Key, int keyOffset, byte[] Cypher, int cypherOffset)
{
byte szParityKey[] = new byte[8];
parity_key(szParityKey, Key, keyOffset);

IBlockCipher cipher = CipherFactory.getInstance("DES");
Map attributes = new HashMap();

attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(8));
attributes.put(IBlockCipher.KEY_MATERIAL, szParityKey);

try
{
cipher.init(attributes);
cipher.encryptBlock(Clear, clearOffset, Cypher, cypherOffset);
}
catch (WeakKeyException e) { }
catch (Exception e)
{
e.printStackTrace();
}
}

private static byte[] ChallengeResponse(final byte[] Challenge, final byte[] PasswordHash)
{
byte Response[] = new byte[24];
byte ZPasswordHash[] = new byte[21];

for (int i = 0; i < 16; i++)
ZPasswordHash[i] = PasswordHash[i];

for (int i = 16; i < 21; i++)
ZPasswordHash[i] = 0;

DesEncrypt(Challenge, 0, ZPasswordHash, 0, Response, 0);
DesEncrypt(Challenge, 0, ZPasswordHash, 7, Response, 8);
DesEncrypt(Challenge, 0, ZPasswordHash, 14, Response, 16);

return Response;
}

private static byte[] NtChallengeResponse(byte[] Challenge, byte[] Password)
{
byte[] PasswordHash = NtPasswordHash(Password);
return ChallengeResponse(Challenge, PasswordHash);
}

private static byte[] GenerateNTResponse(byte[] AuthenticatorChallenge, byte[] PeerChallenge, byte[] UserName, byte[] Password)
{
byte Challenge[] = ChallengeHash(PeerChallenge, AuthenticatorChallenge, UserName);
byte PasswordHash[] = NtPasswordHash(Password);
return ChallengeResponse(Challenge, PasswordHash);
}

public static void DesHash(byte[] key, int offsetKey, byte[] Cypher, int offsetCypher)
{
/*
* Make Cypher an irreversibly encrypted form of Clear by
* encrypting known text using Clear as the secret key.
* The known text consists of the string
*
* KGS!@#$%
*/
String ClearText = "KGS!@#$%";
DesEncrypt(ClearText.getBytes(), 0, key, offsetKey, Cypher, offsetCypher);
}

public static byte[] LmPasswordHash(byte[] Password)
{
String pString = (new String(Password)).toUpperCase();
byte[] PasswordHash = new byte[16];
byte[] pByte = new byte[14];

for (int i=0; i<14; i++) pByte[i] = 0;

Password = pString.getBytes();
for (int i=0; i < 14 && i < Password.length; i++)
pByte[i] = Password[i];

DesHash(pByte, 0, PasswordHash, 0);
DesHash(pByte, 7, PasswordHash, 8);

return PasswordHash;
}

public static byte[] LmChallengeResponse(byte[] Challenge, byte[] Password)
{
byte[] PasswordHash = LmPasswordHash(Password);
return ChallengeResponse(Challenge, PasswordHash);
}

/**
* Do MSCHAPv1 (supports using NT Password)
*
* @param Password The User's Password value in bytes
* @param AuthChallenge The 16 byte authentication challenge
* @return Returns a 50 byte array - the MSCHAP Response
*/
public static byte[] doMSCHAPv1(byte[] Password, byte[] AuthChallenge)
{
byte[] Response = new byte[50];
// There is currently a problem with the LmChallengeResponse value!
byte[] LmResponse = LmChallengeResponse(AuthChallenge, Password);
byte[] NtResponse = NtChallengeResponse(AuthChallenge, Password);
System.arraycopy(LmResponse, 0, Response, 2, 24);
System.arraycopy(NtResponse, 0, Response, 26, 24);
// Lets only use the NT password
Response[1] = 0x01;
return Response;
}

/**
* Do MSCHAPv2
*
* @param UserName The User-Name attribute value bytes
* @param Password The User's Password value in bytes
* @param AuthChallenge The 16 byte authentication challenge
* @return Returns a 50 byte array - the MSCHAPv2 Response
*/
public static byte[] doMSCHAPv2(byte[] UserName, byte[] Password, byte[] AuthChallenge)
{
byte[] Response = new byte[50];
byte peerChallenge[] = RadiusRandom.getBytes(16);
byte ntResponse[] = GenerateNTResponse(AuthChallenge, peerChallenge, UserName, Password);
System.arraycopy(peerChallenge, 0, Response, 2, 16);
System.arraycopy(ntResponse, 0, Response, 26, 24);
return Response;
}
}
Posted
Comments
Xiao Ling 8-Aug-14 5:27am    
Please make your effort first.
xiangwenb 8-Aug-14 6:48am    
I'm not familiar with Java language
hypermellow 8-Aug-14 5:28am    
What have you tried, where are you stuck?
xiangwenb 8-Aug-14 6:49am    
I am not familiar with the Java language, so to help
[no name] 8-Aug-14 7:08am    
We are not a code translation service.

 
Share this answer
 
Comments
xiangwenb 8-Aug-14 6:56am    
Conversion error, cannot be converted correctly
Dave Kreskowiak 8-Aug-14 10:32am    
There is no tool that will do the conversion for you perfectly. YOU are going to have to at least fix the code by hand yourself. Nobody is going to do the work for you.
xiangwenb 8-Aug-14 20:37pm    
Thank you, I finished

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900