java 整合Ucenter (authcode)函数的算法


自己用java整合ucenter,发现网上的都不能用。看看下php的authcode,照着写了下,发现怎么写都会有个bug,请高手搞一下。
---接口
package com.hq.encryptor;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.hq.encryptor.iface.PasswordEnDe;

/**
* Ucenter论坛可逆加密算法
* bug:解密后的字符串可能多一个或者2个字符。谁解决了请发我信箱supttkl@163.com
* @author GAO
*
*/
public class UcenterPasswordEncryptor implements PasswordEnDe {
// 密钥字符串
private String ENCRYPTOR_KEY = "1234567890";
private BASE64Decoder decoder = new BASE64Decoder();
private BASE64Encoder encoder = new BASE64Encoder();

public UcenterPasswordEncryptor() {

}

/**
* @param key 密钥
*/
public UcenterPasswordEncryptor(String key) {
this.ENCRYPTOR_KEY = key;
}

// 加密
public String encrypt(String password) {
try {
password=URLEncoder.encode(password, "UTF-8");//支持中文
String key = ENCRYPTOR_KEY;
int ckey_length = 4;
key = getMd5String(key);
String keya = getMd5String(key.substring(0, 16));
String keyb = getMd5String(key.substring(16, 32));
String min = String.valueOf(System.currentTimeMillis());
min = "0.00000000 " + min.substring(0, min.length() - 3);
String keyc = ckey_length > 0 ? getMd5String(String.valueOf(min))
: "";
keyc = keyc.substring(keyc.length() - 4, keyc.length());
String cryptkey = keya + getMd5String(keya + keyc);
int key_length = cryptkey.length();
byte[] temp = null;
String str_temp = "0000000000"
+ getMd5String(password + keyb).substring(0, 16) + password;
temp = str_temp.getBytes("UTF-8");
int[] box = new int[256];
for (int i = 0; i < box.length; i++) {
box[i] = i;
}

char[] rndkey = new char[256];
for (int i = 0; i <= 255; i++) {
rndkey[i] = cryptkey.charAt(i % key_length);
}

for (int j = 0, i = 0; i < 256; i++) {
j = (j + box[i] + (int) rndkey[i]) % 256;
int tmp = box[i];
box[i] = box[j];
box[j] = tmp;
}
for (int a = 0, j = 0, i = 0; i < temp.length; i++) {
a = (a + 1) % 256;
j = (j + box[a]) % 256;
int tmp = box[a];
box[a] = box[j];
box[j] = tmp;
int gao = (int) temp[i];
byte c = (byte) (gao ^ (box[(box[a] + box[j]) % 256]));
temp[i] = c;
}
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(
temp);
encoder.encode(((InputStream) (bytearrayinputstream)),
((OutputStream) (bytearrayoutputstream)));
String s = bytearrayoutputstream.toString();
return keyc + s.replace("=", "");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private String getMd5String(String password)
throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] input = md.digest(password.getBytes());
String hex = byteToHexString(input);
return hex;
}

private String byteToHexString(byte[] res) {
StringBuffer sb = new StringBuffer(res.length << 1);
for (int i = 0; i < res.length; i++) {
String digit = Integer.toHexString(0xFF & res[i]);
if (digit.length() == 1) {
digit = '0' + digit;
}
sb.append(digit);
}
return sb.toString();
}
//
public boolean matches(String passwordToCheck, String storedPassword) {
if(storedPassword == null) {
throw new NullPointerException("storedPassword can not be null");
}
if(passwordToCheck == null) {
throw new NullPointerException("passwordToCheck can not be null");
}

return encrypt(passwordToCheck).equals(storedPassword);
}

// 解密
public String decrypt(String password) {
try {

int ckey_length = 4;
String key = getMd5String(ENCRYPTOR_KEY);
String keya = getMd5String(key.substring(0, 16));
String min = String.valueOf(System.currentTimeMillis());
min = "0.00000000 " + min.substring(0, min.length() - 3);

String keyc = ckey_length > 0 ? password.substring(0, ckey_length)
: "";
String cryptkey = keya + getMd5String(keya + keyc);
int key_length = cryptkey.length();
byte[] temp = null;
if(true){//这步为出bug的地方
String t1 = password.substring(ckey_length, password.length());
ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(t1.getBytes("UTF-8"));
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
decoder.decodeBuffer(((InputStream) (bytearrayinputstream)), ((OutputStream) (bytearrayoutputstream)));
temp=bytearrayoutputstream.toByteArray();
}

int[] box=new int[256];
for (int i = 0; i <box.length; i++) {
box[i] = i;
}

char[] rndkey = new char[256];
for (int i = 0; i <= 255; i++) {
rndkey[i] = cryptkey.charAt(i % key_length);
}

for (int j = 0, i = 0; i < 256; i++) {
j = (j + box[i] + (int) rndkey[i]) % 256;
int tmp = box[i];
box[i] = box[j];
box[j] = tmp;
}
StringBuffer sb = new StringBuffer();
for(int a =0, j=0, i = 0; i < temp.length; i++) {
a = (a + 1) % 256;
j = (j + box[a]) % 256;
int tmp = box[a];
box[a] = box[j];
box[j] = tmp;
int gao=(int)temp[i]<0? (int)temp[i]+256:(int)temp[i];
char c =(char)(gao ^ (box[(box[a] + box[j]) % 256]));
sb.append(c);
}
String lastStr= sb.substring(26, sb.length());
return URLDecoder.decode(lastStr, "UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值