发一个java版的passport工具类
[code]import java.util.Map;import java.util.Random;
import java.util.Set;
import sun.misc.BASE64Decoder;
/**
*
* @author 李杰
*
*/
public class DiscuzPassportUtils {
public static String passportEncrypt(String src, String key) {
Random random = new Random();
random.setSeed(System.currentTimeMillis());
String rand = "" + random.nextInt() % 32000;
String encryptKey = EncryptUtil.encrypt(rand, "MD5");
int ctr = 0;
String tmp = "";
for (int i = 0; i < src.length(); ++i) {
ctr = (ctr == encryptKey.length() ? 0 : ctr);
tmp += encryptKey.charAt(ctr);
char c = (char) (src.charAt(i) ^ encryptKey.charAt(ctr));
tmp += c;
ctr++;
}
String passportKey = passportKey(tmp, key);
return new sun.misc.BASE64Encoder().encode(passportKey.getBytes());
}
public static String passortDecrypt(String src, String key) {
byte[] bytes = null;
try {
bytes = new BASE64Decoder().decodeBuffer(src);
src = new String(bytes);
} catch (Exception e) {
return null;
}
src = passportKey(src, key);
String tmp = "";
for (int i = 0; i < src.length(); ++i) {
char c = (char)(src.charAt(i) ^ src.charAt(++i));
tmp += c;
}
return tmp;
}
public static String passportKey(String src, String key) {
String encryptKey = EncryptUtil.encrypt(key, "MD5");
int ctr = 0;
String tmp = "";
for (int i = 0; i < src.length(); ++i) {
ctr = (ctr == encryptKey.length() ? 0 : ctr);
char c = (char) (src.charAt(i) ^ encryptKey.charAt(ctr));
tmp += c;
ctr++;
}
return tmp;
}
public static String passportEncode(Map<String, String> data) {
Set<String> keys = data.keySet();
String ret = "";
for (String key : keys) {
ret += key + "=" + data.get(key) + "&";
}
if (ret.length() > 0)
return ret.substring(0, ret.length() - 1);
return "";
}
}[/code]
从D4文档的“高级应用”->“Discuz! Passport 接口技术文档”里面差不多,本代码从那个php版本转换过来。下面是使用代码:
[code]
Map<String, String> member = new LinkedHashMap<String, String>();
member.put("cookietime", "31536000");
member.put("time", "1117415922");
member.put("username", "Abcd");
member.put("password", "e2fc714c4727ee9395f324cd2e7f331f");
member.put("email", "abcd@efgh.com");
member.put("credits", "123");
member.put("regip", "210.120.222.111");
member.put("regdate", "1012752000");
member.put("msn", "email@hotmail.com");
String key="aa";
String enc=DiscuzPassportUtils.passportEncode(member);
String auth = DiscuzPassportUtils.passportEncrypt(enc, key);
System.out.println(auth); // 输出加密结果
enc = DiscuzPassportUtils.passortDecrypt(auth, key);
System.out.println(enc); // 输出解密结果
// 1000次调用
long start = System.currentTimeMillis();
for (int i=0; i<1000; ++i){
enc = DiscuzPassportUtils.passportEncode(member);
auth = DiscuzPassportUtils.passportEncrypt(enc, key);
}
System.out.println(System.currentTimeMillis() - start);
[/code]
在我的机器上,1000次调用时间是1.8秒。 我不懂 [quote]原帖由 [i]紫云杉[/i] 于 2006-1-4 11:28 发表
我不懂 [/quote]
晕,怎么灌得这么快?发了还没10秒就有回复了? [quote]原帖由 [i]lovaling[/i] 于 2006-1-4 11:29 发表
晕,怎么灌得这么快?发了还没10秒就有回复了? [/quote]
;P 起什麼作用的 [quote]原帖由 [i]741147[/i] 于 2006-1-4 12:58 发表
起什麼作用的 [/quote]
你看一下D4的文档就知道了,高级应用->Discuz! Passport 接口技术文档 里面,网站整合用的。
如果你有一个java开发的网站,D4要调用你那个网站的注册、登录、退出等功能,需要对一些信息加密传送到论坛,上面就是一些加密的函数。
试过了吗?
试过能用嘛?感觉你这个缺少点东西:passportEncode里面的需要URLEncoder.encode吧。另外我这里BASE64Encode出来的是有空格的。还有我这里用另外的包做的MD5.不知道你的EncryptUtil是否返回的MD5字符串是大写还是小写。注意论坛需要小写的,大写的是不行的。请求发全了。
改进一下吧,最好能够将整个都测试以下,然后发一个全的文件上来。passport调试失败,进不去论坛了。
急啊,怎么办哪?另外如果passport成功管理界面应该单独登录吧. 不会JAVA..纯支持~~ 我已经用上了,URLEncode.encode是要调用的,原来是让使用者来调用的,后来想想这也是个普遍的需求,就放到里面了,新的代码如下:[code]import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import sun.misc.BASE64Decoder;
/**
*
* @author 李杰
*
*/
public class DiscuzPassportUtils {
public static String passportEncrypt(String src, String key) {
Random random = new Random();
random.setSeed(System.currentTimeMillis());
String rand = "" + random.nextInt() % 32000;
String encryptKey = EncryptUtil.encrypt(rand, "MD5");
int ctr = 0;
String tmp = "";
for (int i = 0; i < src.length(); ++i) {
ctr = (ctr == encryptKey.length() ? 0 : ctr);
tmp += encryptKey.charAt(ctr);
char c = (char) (src.charAt(i) ^ encryptKey.charAt(ctr));
tmp += c;
ctr++;
}
String passportKey = passportKey(tmp, key);
return new sun.misc.BASE64Encoder().encode(passportKey.getBytes());
}
public static String passortDecrypt(String src, String key) {
byte[] bytes = null;
try {
bytes = new BASE64Decoder().decodeBuffer(src);
src = new String(bytes);
} catch (Exception e) {
return null;
}
src = passportKey(src, key);
String tmp = "";
for (int i = 0; i < src.length(); ++i) {
char c = (char)(src.charAt(i) ^ src.charAt(++i));
tmp += c;
}
return tmp;
}
public static String passportKey(String src, String key) {
String encryptKey = EncryptUtil.encrypt(key, "MD5");
int ctr = 0;
String tmp = "";
for (int i = 0; i < src.length(); ++i) {
ctr = (ctr == encryptKey.length() ? 0 : ctr);
char c = (char) (src.charAt(i) ^ encryptKey.charAt(ctr));
tmp += c;
ctr++;
}
return tmp;
}
public static String passportEncode(Map<String, String> data) {
Set<String> keys = data.keySet();
String ret = "";
for (String key : keys) {
try {
ret += java.net.URLEncoder.encode(key, "UTF-8") + "=" + java.net.URLEncoder.encode(data.get(key), "UTF-8") + "&";
} catch (UnsupportedEncodingException e) {
return "";
}
}
if (ret.length() > 0)
return ret.substring(0, ret.length() - 1);
return "";
}
}[/code] 同事写的调用代码:
[code]//给论坛返回验证
Map<String, String> mb = new LinkedHashMap<String, String>();
mb.put("cookietime", cookieTime);
mb.put("time", ""+System.currentTimeMillis());
mb.put("username", member.getLoginName());
mb.put("password", loginForm.getPassword());
mb.put("email", member.getEmail());
mb.put("credits", ""+member.getCredit());
mb.put("regdate", ""+member.getCreateTime().getTime());
String key = privateKey;
String enc=DiscuzPassportUtils.passportEncode(mb);
String auth = DiscuzPassportUtils.passportEncrypt(enc, key);
String verify = "login" + auth + forward + key;
verify = EncryptUtil.encrypt(verify, "MD5");
String location = forumURL+"/api/passport.php?action=login&auth="+URLEncoder.encode(auth, "UTF-8")+"&forward="+URLEncoder.encode(forward, "UTF-8")+"&verify="+URLEncoder.encode(verify, "UTF-8");[/code]
下面那行就是用来跳转的,写得有点长,不过是正确的,要写得好看些可以使用String.format。 一并把退出代码发出来:
//给论坛返回验证
String key = privateKey;
String verify = "logout" + forward + key;
verify = EncryptUtil.encrypt(verify, "MD5");
String location = forumURL+"/api/passport.php?action=logout&forward="+URLEncoder.encode(forward, "UTF-8")+"&verify="+URLEncoder.encode(verify, "UTF-8");
感谢楼主发布的JAVA版类
特此奉上.net版的,按JAVA版和官方说明写的 测试通过[code]
public class DiscuzPassport
{
public DiscuzPassport()
{
//
// TODO: Add constructor logic here
//
}
public static string passportEncrypt(string txt, string key)
{
Random rd = new Random();
string rand = rd.Next(0, 32000).ToString();
string encryptKey = FormsAuthentication.HashPasswordForStoringInConfigFile(rand, "MD5").ToLower();
int ctr = 0;
string tmp = "";
for (int i = 0; i < txt.Length; i++)
{
ctr = (ctr == encryptKey.Length ? 0 : ctr);
tmp += encryptKey[ctr].ToString();
char c = (char)(txt[i] ^ encryptKey[ctr]);
tmp += c;
ctr++;
}
string passportkey = passportKey(tmp, key);
return base64Encode(passportkey);
}
public static string base64Encode(string data)
{
try
{
byte[] encData_byte = new byte[data.Length];
encData_byte = System.Text.Encoding.UTF8.GetBytes(data);
string encodedData = Convert.ToBase64String(encData_byte);
return encodedData;
}
catch (Exception e)
{
throw new Exception("Error in base64Encode" + e.Message);
}
}
public static string base64Decode(string data)
{
try
{
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Text.Decoder utf8Decode = encoder.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(data);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
char[] decoded_char = new char[charCount];
utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
string result = new String(decoded_char);
return result;
}
catch (Exception e)
{
throw new Exception("Error in base64Decode" + e.Message);
}
}
public static string passportKey(string txt, string key)
{
string encryptKey = FormsAuthentication.HashPasswordForStoringInConfigFile(key, "MD5").ToLower();
int ctr = 0;
string tmp = "";
for (int i = 0; i < txt.Length; i++)
{
ctr = (ctr == encryptKey.Length ? 0 : ctr);
char c = (char)(txt[i] ^ encryptKey[ctr]);
tmp += c;
ctr++;
}
return tmp;
}
public static string passortDecrypt(string txt, string key)
{
txt = base64Decode(txt);
txt = passportKey(txt, key);
string tmp = "";
for (int i = 0; i < txt.Length; i++)
{
char c = (char)(txt[i] ^ txt[i++]);
tmp += c;
}
return tmp;
}
public static string passportEncode(Hashtable ht)
{
string r="";
foreach (string key in ht.Keys)
{
r += key + "=" + ht[key].ToString()+"&";
}
if (r.Length > 0)
r = r.TrimEnd('&');
return r;
}
}
[/code] 调用请用hashtable JAVA 技术要求更高,国内门户只有网易一家采用了JSP,像QQ和SINA这种只用了CGI。。。 不懂啊,郁闷 你使用了一个EncryptUtil,没这个代码 哈哈,李老大,你也在这里溜达呀!
我说代码咋那么眼熟,原来我写了一点,哈哈
回复 #19 flmnix 的帖子
EncryptUtil的功能是加密字符串,用到java.security.MessageDigest页:
[1]
2

