SIPC的认证算法,支持SHA1和MD5。
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Random;
/**
* @author zackel
* @date 2007-11-22 21:38:07
* @project
*/
public class GenAuthResponse {
// Fields
private String cnonce;
private String domain;
private String nonce;
private String password;
private static Random random;
private String sid;
private boolean usingSHA1=false;
private String salt;
private String encryptPassword;
public void setSalt(String salt) {
this.salt = salt;
}
public String getEncryptPassword() {
return encryptPassword;
}
public void setEncryptPassword(String encryptPassword) {
this.encryptPassword = encryptPassword;
}
public String getSalt() {
return salt;
}
// public void setSalt(String salt) {
// this.salt = salt;
// }
public boolean isUsingSHA1() {
return usingSHA1;
}
public void setUsingSHA1(boolean usingSHA1) {
this.usingSHA1 = usingSHA1;
}
public String getCnonce() {
return this.cnonce;
}
public void setCnonce(String cnonce) {
this.cnonce = cnonce;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getNonce() {
return nonce;
}
public void setNonce(String nonce) {
this.nonce = nonce;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
// Methods
public GenAuthResponse(String sid, String password, String domain, String nonce)
{
this.sid = sid;
this.password = password;
this.domain = domain;
this.nonce = nonce;
Calendar cal = new GregorianCalendar();
int seed = cal.get(Calendar.DAY_OF_YEAR) * 0xf4240;
seed += cal.get(Calendar.HOUR) * 0x2710;
seed += cal.get(Calendar.MINUTE) * 100;
seed += cal.get(Calendar.SECOND);
// random = new Random(System.currentTimeMillis());
random = new Random(seed);
this.cnonce = GenCNonce();
this.salt=GenSalt();
// System.out.println(salt);
}
private static String BinToHex(byte[] binary)
{
// StringBuilder builder = new StringBuilder();
// for(byte num : binary)
// {
// int n = num;
// if (n < 0)
// n = n &0xff;
//
// if ((int)n > 15)
// {
// builder.append(String.format("%X",n));
//
// }
// else
// {
// builder.append(String.format("0%X",n));
//
// }
// }
System.out.println(builder.toString());
// return builder.toString();
if (binary == null)
return "null";
if (binary.length == 0)
return "";
StringBuilder buf = new StringBuilder();
for (int i = 0; i < binary.length; i++) {
if (binary[i] < 0)
buf.append(Integer.toHexString(binary[i]&0xff));
else if (binary[i] < 16) {
buf.append('0');
buf.append(Integer.toHexString(binary[i]));
} else {
buf.append(Integer.toHexString(binary[i]));
}
}
return buf.toString().toUpperCase();
}
private String GenH1(byte[] key)
{
String s = String.format(":%s:%s", this.nonce, this.getCnonce());
// System.out.println("nonce:"+this.nonce );
// System.out.println("Cnonce:"+this.getCnonce());
// System.out.println(s);
byte[] bytes;
try {
// bytes = s.getBytes("UTF-8");
bytes=new String(s.getBytes(),"utf-8").getBytes();
// System.out.println("h1 bytes:"+this.BinToHex(bytes));
byte[] array = new byte[key.length + bytes.length];
System.arraycopy(key,0,array,0,key.length);
System.arraycopy(bytes, 0, array, key.length, bytes.length);
// System.out.println("h1 array:"+this.BinToHex(array));
return MD5ToHex(array);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private String GenH2()
{
String s = String.format("REGISTER:%s", this.sid);
// System.out.println(s);
try {
// return MD5ToHex(s.getBytes("UTF-8"));
return MD5ToHex(new String(s.getBytes(),"utf-8").getBytes());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private byte[] GenKey()
{
if(this.usingSHA1==true){
String s1 = String.format("%s:%s:", this.sid, this.domain);
// System.out.println(s1);
try {
this.encryptPassword=DoHashPassword(this.password);
// System.out.println("GenKey enc psw:");
// System.out.println(this.encryptPassword);
byte[] bytes=(new String(s1.getBytes(),"utf-8").getBytes());
// System.out.println("GenKey bytes:"+BinToHex(bytes));
byte[] src=this.HexToBin(this.encryptPassword.substring(8));//和C#定义不一样?
// System.out.println("psw0-8:"+BinToHex(src));
// byte[] src=this.HexToBin(this.salt);
byte[] dst=new byte[bytes.length +src.length ];
System.arraycopy(bytes,0,dst,0,bytes.length);
System.arraycopy(src,0,dst,bytes.length,src.length);
// System.out.println("GenKey dst:"+BinToHex(dst));
return new SHA1().getDigestOfBytes(dst);
} catch (UnsupportedEncodingException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
String s = String.format("%s:%s:%s", this.sid, this.domain, this.password);
// System.out.println(s);
try {
// return MD5(s.getBytes("UTF-8"));
return MD5(new String(s.getBytes(),"utf-8").getBytes());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public String GenResponse()
{
byte[] key = this.GenKey();
// System.out.println("Key:");
// System.out.println(this.BinToHex(key));
String str = this.GenH1(key);
// System.out.println("H1:");
// System.out.println(str);
String str2 = this.GenH2();
// System.out.println("H2:");
// System.out.println(str2);
return this.GenResponse(str, str2);
}
private String GenResponse(String h1, String h2)
{
String s = String.format("%s:%s:%s", h1, this.nonce, h2);
// System.out.println(s);
try {
// return MD5ToHex(s.getBytes("UTF-8"));
return MD5ToHex(new String(s.getBytes(),"utf-8").getBytes());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private String GenCNonce()
{
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
synchronized (random)
{
num = random.nextInt();
num2 = random.nextInt();
num3 = random.nextInt();
num4 = random.nextInt();
}
if ((num >> 0x18) < 0x10)
{
num += 0x10000000;
}
if ((num2 >> 0x18) < 0x10)
{
num2 += 0x10000000;
}
if ((num3 >> 0x18) < 0x10)
{
num3 += 0x10000000;
}
if ((num4 >> 0x18) < 0x10)
{
num4 += 0x10000000;
}
return String.format("%X%X%X%X", new Object[] { num, num2, num3, num4 });
//
}
private static byte[] HexToBin(String hex)
{
hex=hex.toUpperCase();
if ((hex == null) || (hex.length() < 1))
{
return new byte[0];
}
int num = hex.length() / 2;
byte[] buffer = new byte[num];
num *= 2;
for (int i = 0; i < num; i++)
{
// System.out.println(hex.substring(i, i+2));
char c1,c2;
c1=hex.substring(i,i+1).charAt(0);
c2=hex.substring(i+1, i+2).charAt(0);
// System.out.println(c1);
if(c1>='A')
c1=(char) (10+c1-'A');
else
c1=(char) (c1-'0');
if(c2>='A')
c2=(char) (10+c2-'A');
else
c2=(char) (c2-'0');
// System.out.println(c1-'A');
// System.out.println(c2);
// System.out.println(c1*16+c2);
int num3=c1*16+c2;
// int num3 = Integer.parseInt(hex.substring(i, i+2));
buffer[i / 2] = (byte) num3;
i++;
}
// System.out.println(BinToHex(buffer));
return buffer;
}
private byte[] MD5(byte[] data)
{
return MD5Util.MD5Encode(data);
}
private String MD5ToHex(byte[] data)
{
// data = MD5(data);
return BinToHex(MD5(data));
}
public String DoHashPassword(String _password){
try {
return DoHashPassword(new String(_password.getBytes(),"utf-8").getBytes(),this.HexToBin(this.salt));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public String DoHashPassword(byte[] password, byte[] b0)
{
SHA1 sha=SHA1.Create();
byte[] src = sha.getDigestOfBytes(password);
// System.out.println("psw sha1:");
// System.out.println(this.BinToHex(src));
for (int i = 0; i < password.length; i++)
{
password[i] = 0;
}
byte[] dst = new byte[b0.length + src.length];
System.arraycopy(b0, 0, dst, 0, b0.length);
System.arraycopy(src, 0, dst, b0.length, src.length);
byte[] buffer3 = sha.getDigestOfBytes(dst);
// System.out.println("buffer3 sha1:");
// System.out.println(this.BinToHex(buffer3));
byte[] buffer4 = new byte[b0.length + buffer3.length];
System.arraycopy(b0, 0, buffer4, 0, b0.length);
System.arraycopy(buffer3, 0, buffer4, b0.length, buffer3.length);
// System.out.println("enc psw:");
// System.out.println(this.BinToHex(buffer4));
return this.BinToHex(buffer4);
}
public String GenSalt(){
byte[] salt = new byte[4];
synchronized (random)
{
salt[0] = (byte)random.nextInt(255);
salt[1] = (byte)random.nextInt(255);
salt[2] = (byte)random.nextInt(255);
salt[3] = (byte)random.nextInt(255);
// System.out.println(salt[3]);
return this.BinToHex(salt);
// return salt;
}
}
// public static String EncodePassword(byte[] password, byte[] b0)
// {
// using (SHA1 sha = SHA1.Create())
// {
// byte[] src = sha.ComputeHash(password);
// for (int i = 0; i < password.Length; i++)
// {
// password[i] = 0;
// }
// byte[] dst = new byte[b0.Length + src.Length];
// Buffer.BlockCopy(b0, 0, dst, 0, b0.Length);
// Buffer.BlockCopy(src, 0, dst, b0.Length, src.Length);
// byte[] buffer3 = sha.ComputeHash(dst);
// byte[] buffer4 = new byte[b0.Length + buffer3.Length];
// Buffer.BlockCopy(b0, 0, buffer4, 0, b0.Length);
// Buffer.BlockCopy(buffer3, 0, buffer4, b0.Length, buffer3.Length);
// return BinaryToHex(buffer4);
// }
// }
// public static String BinaryToHex(byte[] binary)
// {
// StringBuilder builder = new StringBuilder();
// for(byte num:binary)
// {
// if (num > 15)
// {
// builder.("{0:X}", num);
// }
// else
// {
// builder.AppendFormat("0{0:X}", num);
// }
// }
// return builder.toString();
// }
// public static void main(String[] args){
// GenAuthResponse genAuthResponse=new GenAuthResponse("759909","A","fetion.com.cn", "250BA679516452E860C02B1638D52849");
// genAuthResponse.setUsingSHA1(true);
// genAuthResponse.setCnonce("798AC8BD240DABB21C9259C8148373F2");
// genAuthResponse.setSalt("FD761703");
//
genAuthResponse.HexToBin("E0FF0100");
// System.out.println(genAuthResponse.GenResponse());
System.out.println(genAuthResponse.getCnonce());
//
Random random = new Random(10);
int i=random.nextInt(9);
// int num3;
System.out.println(num3 = Integer.parseInt("0x5A"));
//
// }
}