这个问题我已经在csdn上问了些日子了,但是一直没有得到解答,所以我想在再这里问问看。
http://topic.csdn.net/u/20070924/15/36acdd36-e57e-4b93-8975-64950b8d5e4d.html
因为要使用dz的通行证,其中需要使用azdg对传输的数据进行加密解密,而我的程序是asp.net 所以我必须也得实现一个.net版本。
我照着php下的算法写了一个,如果是英文字符什么的话是可以正确的加密、解密的,但是当我使用中文时就不能正确工作。
public class Azdg
{
public static string passport_encrypt(string txt, string key)
{
// 使用随机数发生器产生 0~32000 的值并 MD5()
Random rnd = new Random(100);
int int_encrypt_key = rnd.Next(0, 32000);
string encrypt_key = int_encrypt_key.ToString();
int ctr = 0;
string tmp = "";
byte[] encodebyte = new byte[txt.Length];
for (int i = 0; i < txt.Length; i++)
{
ctr = ctr == encrypt_key.Length ? 0 : ctr;
char prefix = encrypt_key[ctr];
char left = txt[i];
char right = encrypt_key[ctr++];
encodebyte[i] = (byte)(left ^ right);
char[] block = new char[2];
block[0] = prefix;
block[1] = Convert.ToChar(encodebyte[i]);
tmp+=new string(block);
}
//////用base64编码
string complicatedstring = passport_key(tmp, key);/////先和key加一次密?
byte[] inputbytes=System.Text.Encoding.Default.GetBytes(complicatedstring);
string string_64=Convert.ToBase64String(inputbytes, 0, inputbytes.Length);/////再和随机key加密
return string_64;
}
/// <summary >
/// Passport 解密函数
/// </summary >
/// <param name="txt" >加密后的字串 </param >
/// <param name="key" >私有密匙(用于解密和加密) </param >
/// <returns >字串经过私有密匙解密后的结果 </returns >
public static string passport_decrypt(string txt, string key)
{
byte[] array_64=Convert.FromBase64String(txt);
string txt_64 = System.Text.Encoding.Default.GetString(array_64);
txt = passport_key(txt_64, key);
string temp = "";
byte[] encodebyte = new byte[txt.Length];
for (int i = 0; i < txt.Length; i++)
{
char left = txt[i];
char right = txt[++i];
encodebyte[i] = (byte)(left ^ right);
}
temp = System.Text.Encoding.Default.GetString(encodebyte);
return temp;
}
/// <summary >
/// Passport 密匙处理函数
/// </summary >
/// <param name="txt" >待加密或待解密的字串 </param >
/// <param name="encrypt_key" >私有密匙(用于解密和加密) </param >
/// <returns >处理后的密匙 </returns >
public static string passport_key(string txt, string encrypt_key)
{
/////////////先md5编码
encrypt_key =
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(encrypt_key, "MD5").ToString().ToLower();
int ctr = 0;
string tmp = "";
byte[] encodebyte = new byte[txt.Length];
for (int i = 0; i < txt.Length; i++)
{
ctr = ctr == encrypt_key.Length ? 0 : ctr;
char left = txt[i];
char right = encrypt_key[ctr++];
encodebyte[i] = (byte)(left ^ right);
}
tmp = System.Text.Encoding.Default.GetString(encodebyte);
return tmp;
}
}
我首先执行
string original_stirng = "haha";
string key = "123456";
string enctrypt_string = Azdg.passport_encrypt(original_stirng,key);////////加密
返回的结果是:VmoBMVQ7A2g=
第二次我执行反向过程:
string encrypt_string = "VmoBMVQ7A2g=";
string key = "123456";
string old_string = Azdg.passport_decrypt(encrypt_string, key);
old_string结果是"haha"
这个测试是成功的
之后我在用中文来:
string original_stirng = "大和吉良";
string key = "123456";
string enctrypt_string = Azdg.passport_encrypt(original_stirng,key);////////加密
返回的enctrypt_string="ViUB3FRaA2Y="
在执行反向操作
string encrypt_string = "ViUB3FRaA2Y="";
string key = "123456";
string old_string = Azdg.passport_decrypt(encrypt_string, key);
old_string结果是一堆乱码
我认为是passport_key这个方法导致的问题,当我使用英文字符串时,返回的是和php中的版本是一样的,但是如果是中文的话,这里的结果和php的那个函数是不一样的。
我认为php页面编码和.net 不同导致结果不同是可以理解的,但是我在.net下则应该是相同的编码,所以加密和解密应该是没有问题的,而现在的问题恰恰是在中文时,加密和解密不统一,所以请教大家帮我看看是什么问题呢。
---------------
这份是php下的写法,给大家对照:
/**
* Passport 加密函数
*
* @param string 等待加密的原字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 原字串经过私有密匙加密后的结果
*/
function passport_encrypt($txt, $key) {
// 使用随机数发生器产生 0~32000 的值并 MD5()
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0, 32000));
// 变量初始化
$ctr = 0;
$tmp = " ";
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for($i = 0; $i < strlen($txt); $i++) {
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
// $tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位,
// 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1
$tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
}
// 返回结果,结果为 passport_key() 函数返回值的 base64 编码结果
return base64_encode(passport_key($tmp, $key));
}
/**
* Passport 解密函数
*
* @param string 加密后的字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 字串经过私有密匙解密后的结果
*/
function passport_decrypt($txt, $key) {
// $txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起,
// 经过 passport_key() 函数处理后的返回值
$txt = passport_key(base64_decode($txt), $key);
// 变量初始化
$tmp = " ";
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for ($i = 0; $i < strlen($txt); $i++) {
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
// 与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1
$tmp .= $txt[$i] ^ $txt[++$i];
}
// 返回 $tmp 的值作为结果
return $tmp;
}
/**
* Passport 密匙处理函数
*
* @param string 待加密或待解密的字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 处理后的密匙
*/
function passport_key($txt, $encrypt_key) {
// 将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值
$encrypt_key = md5($encrypt_key);
// 变量初始化
$ctr = 0;
$tmp = " ";
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for($i = 0; $i < strlen($txt); $i++) {
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
// 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
}
// 返回 $tmp 的值作为结果
return $tmp;
}
http://topic.csdn.net/u/20070924/15/36acdd36-e57e-4b93-8975-64950b8d5e4d.html
因为要使用dz的通行证,其中需要使用azdg对传输的数据进行加密解密,而我的程序是asp.net 所以我必须也得实现一个.net版本。
我照着php下的算法写了一个,如果是英文字符什么的话是可以正确的加密、解密的,但是当我使用中文时就不能正确工作。
public class Azdg
{
public static string passport_encrypt(string txt, string key)
{
// 使用随机数发生器产生 0~32000 的值并 MD5()
Random rnd = new Random(100);
int int_encrypt_key = rnd.Next(0, 32000);
string encrypt_key = int_encrypt_key.ToString();
int ctr = 0;
string tmp = "";
byte[] encodebyte = new byte[txt.Length];
for (int i = 0; i < txt.Length; i++)
{
ctr = ctr == encrypt_key.Length ? 0 : ctr;
char prefix = encrypt_key[ctr];
char left = txt[i];
char right = encrypt_key[ctr++];
encodebyte[i] = (byte)(left ^ right);
char[] block = new char[2];
block[0] = prefix;
block[1] = Convert.ToChar(encodebyte[i]);
tmp+=new string(block);
}
//////用base64编码
string complicatedstring = passport_key(tmp, key);/////先和key加一次密?
byte[] inputbytes=System.Text.Encoding.Default.GetBytes(complicatedstring);
string string_64=Convert.ToBase64String(inputbytes, 0, inputbytes.Length);/////再和随机key加密
return string_64;
}
/// <summary >
/// Passport 解密函数
/// </summary >
/// <param name="txt" >加密后的字串 </param >
/// <param name="key" >私有密匙(用于解密和加密) </param >
/// <returns >字串经过私有密匙解密后的结果 </returns >
public static string passport_decrypt(string txt, string key)
{
byte[] array_64=Convert.FromBase64String(txt);
string txt_64 = System.Text.Encoding.Default.GetString(array_64);
txt = passport_key(txt_64, key);
string temp = "";
byte[] encodebyte = new byte[txt.Length];
for (int i = 0; i < txt.Length; i++)
{
char left = txt[i];
char right = txt[++i];
encodebyte[i] = (byte)(left ^ right);
}
temp = System.Text.Encoding.Default.GetString(encodebyte);
return temp;
}
/// <summary >
/// Passport 密匙处理函数
/// </summary >
/// <param name="txt" >待加密或待解密的字串 </param >
/// <param name="encrypt_key" >私有密匙(用于解密和加密) </param >
/// <returns >处理后的密匙 </returns >
public static string passport_key(string txt, string encrypt_key)
{
/////////////先md5编码
encrypt_key =
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(encrypt_key, "MD5").ToString().ToLower();
int ctr = 0;
string tmp = "";
byte[] encodebyte = new byte[txt.Length];
for (int i = 0; i < txt.Length; i++)
{
ctr = ctr == encrypt_key.Length ? 0 : ctr;
char left = txt[i];
char right = encrypt_key[ctr++];
encodebyte[i] = (byte)(left ^ right);
}
tmp = System.Text.Encoding.Default.GetString(encodebyte);
return tmp;
}
}
我首先执行
string original_stirng = "haha";
string key = "123456";
string enctrypt_string = Azdg.passport_encrypt(original_stirng,key);////////加密
返回的结果是:VmoBMVQ7A2g=
第二次我执行反向过程:
string encrypt_string = "VmoBMVQ7A2g=";
string key = "123456";
string old_string = Azdg.passport_decrypt(encrypt_string, key);
old_string结果是"haha"
这个测试是成功的
之后我在用中文来:
string original_stirng = "大和吉良";
string key = "123456";
string enctrypt_string = Azdg.passport_encrypt(original_stirng,key);////////加密
返回的enctrypt_string="ViUB3FRaA2Y="
在执行反向操作
string encrypt_string = "ViUB3FRaA2Y="";
string key = "123456";
string old_string = Azdg.passport_decrypt(encrypt_string, key);
old_string结果是一堆乱码
我认为是passport_key这个方法导致的问题,当我使用英文字符串时,返回的是和php中的版本是一样的,但是如果是中文的话,这里的结果和php的那个函数是不一样的。
我认为php页面编码和.net 不同导致结果不同是可以理解的,但是我在.net下则应该是相同的编码,所以加密和解密应该是没有问题的,而现在的问题恰恰是在中文时,加密和解密不统一,所以请教大家帮我看看是什么问题呢。
---------------
这份是php下的写法,给大家对照:
/**
* Passport 加密函数
*
* @param string 等待加密的原字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 原字串经过私有密匙加密后的结果
*/
function passport_encrypt($txt, $key) {
// 使用随机数发生器产生 0~32000 的值并 MD5()
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0, 32000));
// 变量初始化
$ctr = 0;
$tmp = " ";
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for($i = 0; $i < strlen($txt); $i++) {
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
// $tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位,
// 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1
$tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
}
// 返回结果,结果为 passport_key() 函数返回值的 base64 编码结果
return base64_encode(passport_key($tmp, $key));
}
/**
* Passport 解密函数
*
* @param string 加密后的字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 字串经过私有密匙解密后的结果
*/
function passport_decrypt($txt, $key) {
// $txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起,
// 经过 passport_key() 函数处理后的返回值
$txt = passport_key(base64_decode($txt), $key);
// 变量初始化
$tmp = " ";
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for ($i = 0; $i < strlen($txt); $i++) {
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
// 与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1
$tmp .= $txt[$i] ^ $txt[++$i];
}
// 返回 $tmp 的值作为结果
return $tmp;
}
/**
* Passport 密匙处理函数
*
* @param string 待加密或待解密的字串
* @param string 私有密匙(用于解密和加密)
*
* @return string 处理后的密匙
*/
function passport_key($txt, $encrypt_key) {
// 将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值
$encrypt_key = md5($encrypt_key);
// 变量初始化
$ctr = 0;
$tmp = " ";
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
for($i = 0; $i < strlen($txt); $i++) {
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
// 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
}
// 返回 $tmp 的值作为结果
return $tmp;
}