数据乱码(之 .net 加密)
环境: .net 开发程序用 base64 对某些数据进行加密。然后 oracle 进行解密,并明文存入数据库。
数据库: oracle 10.2.0.1
系统: centos 5.6
1 )
select * from resultedit t where answer is not null and aclass=101
and serialno=2310
1 101 2310 1 11100
2 101 2310 20 050201
3 101 2310 30 专升本
2 )
select d.answer||t.answer from resultedit t ,resultedit d
where t.answer is not null and t.aclass=101
and t.serialno=2310 and t.aclass=d.aclass
截取一部分查询结果
1 专 ?
2 050201
3 11100
4 专 ?
5 050201
6 11100
7 11100 专 ?
8 11100050201
9 1110011100
10 专 ?
11 050201
12 11100
13 专 ?
14 050201
解决方法:
1 、利用 convert 转变 answer 字符串从 ZHS16GBK 到 UTF8 字符集( UTF8 为服务器数据库字符集 )
update resultedit r set r.answer=convert(r.answer, '
UTF8', 'ZHS16GBK')
where r.aclass='101' and r.answer is not null
2 、执行查询:
select d.answer||t.answer from resultedit t ,resultedit d
where t.answer is not null and t.aclass=101
and t.serialno=2310 and t.aclass=d.aclass
1 专升本
2 050201
3 11100
4 专升本
5 050201
6 11100
7 11100 专升本
8 11100050201
9 1110011100
3 、分析根本原因:
开发人员在密码的过程中没有指定数据库的字符集。正确的配置是把字符集修改成服务器数据库的字符集(之前有乱码是因为加密指定的字符集为 default )。红色字体为服务器数据库正确字符集。
#region
加密
public string[] AddPass(string[] args)
{
string[] myanswer = new string[args.Length];
for (int i = 0; i < args.Length; i++)
{
myanswer[i] = Convert.ToBase64String(Encoding.
UTF8.GetBytes(args[i].Trim()));
}
return myanswer;
}
#endregion
#region 解析字符串
public string[,] EnCode(string str, int ccount)
{
string[] strs = str.Substring(0, str.Length).Split('#');
string[,] answer = new string[strs.Length, ccount];
char[] spl = { '-', '>' };
for (int i = 0; i < strs.Length; i++)
{
string[] str2 = strs[i].Split('.');
if (str2[2].Contains("->"))
{
string[] str3 = str2[2].Split('@');
for (int j = 0; j < str3.Length; j++)
{
string[] gst = str3[j].Split(spl);
byte[] mk = Convert.FromBase64String(gst[2].Trim());
string strDecryptParameter = Encoding.
UTF8.GetString(mk);
answer[i, j] = strDecryptParameter;
}
}
else
{
byte[] chd = Convert.FromBase64String(str2[2].Trim());
string mystr = Encoding.
UTF8.GetString(chd);
answer[i, 0] = mystr;
}
}
return answer;
}
#endregion
总结: .net 程序加密,输入数据库的时候一定要指定服务器数据库的字符集相同,不让转码会出现问题。
本人仅仅记录了解决问题的方法与思路。如有错误请您指正,因为我不是开发所以研究的不够深入见谅!
附表: 下文介绍来源于( http://www.supesoft.com/ArticleDisp.asp?ID=4256&Cmd=Print )
///
///
将字符串使用
base64
算法加密
///
///
待加密的字符串
///
System.Text.Encoding
对象,如创建中文编码集对象:
System.Text.Encoding.GetEncoding(54936)
///
public
static
string
EncodingForString(
string
sourceString, System.Text.Encoding ens)
{
return
Convert.ToBase64String(ens.GetBytes(sourceString));
}
///
///
将字符串使用
base64
算法加密
///
///
待加密的字符串
///
public
static
string
EncodingForString(
string
sourceString)
{
return
EncodingForString(sourceString, System.Text.Encoding.GetEncoding(
65001
));
}
///
///
从
base64
编码的字符串中还原字符串,支持中文
///
///
base64
加密后的字符串
///
System.Text.Encoding
对象,如创建中文编码集对象:
System.Text.Encoding.GetEncoding(54936)
///
public
static
string
DecodingForString(
string
base64String, System.Text.Encoding ens)
{
/**
* ***********************************************************
*
*
从
base64String
中取得的字节值为字符的机内码(
ansi
字符编码)
*
一般的,用机内码转换为汉字是公式:
* (char)(
第一字节的二进制值
*256+
第二字节值
)
*
而在
c#
中的
char
或
string
由于采用了
unicode
编码,就不能按照上面的公式计算了
* ansi
的字节编和
unicode
编码不兼容
*
故利用
.net
类库提供的编码类实现从
ansi
编码到
unicode
代码的转换
*
* GetEncoding
方法依赖于基础平台支持大部分代码页。但是,对于下列情况提供系统支持:默认编码,即在执行此方法的计算机的区域设置中指定的编码;
Little-Endian Unicode (UTF-16LE)
;
Big-Endian Unicode (UTF-16BE)
;
Windows
操作系统
(windows-1252)
;
UTF-7
;
UTF-8
;
ASCII
以及
GB18030
(简体中文)。
*
*
指定下表中列出的其中一个名称以获取具有对应代码页的系统支持的编码。
*
*
代码页
名称
* 1200 “UTF-16LE”
、
“utf-16”
、
“ucs-2”
、
“unicode”
或
“ISO-10646-UCS-2”
* 1201 “UTF-16BE”
或
“unicodeFFFE”
* 1252 “windows-1252”
* 65000 “utf-7”
、
“csUnicode11UTF7”
、
“unicode-1-1-utf-7”
、
“unicode-2-0-utf-7”
、
“x-unicode-1-1-utf-7”
或
“x-unicode-2-0-utf-7”
* 65001 “utf-8”
、
“unicode-1-1-utf-8”
、
“unicode-2-0-utf-8”
、
“x-unicode-1-1-utf-8”
或
“x-unicode-2-0-utf-8”
* 20127 “us-ascii”
、
“us”
、
“ascii”
、
“ANSI_X3.4-1968”
、
“ANSI_X3.4-1986”
、
“cp367”
、
“csASCII”
、
“IBM367”
、
“iso-ir-6”
、
“ISO646-US”
或
“ISO_646.irv:1991”
* 54936 “GB18030”
*
*
某些平台可能不支持特定的代码页。例如,
Windows 98
的美国版本可能不支持日语
Shift-jis
代码页(代码页
932
)。这种情况下,
GetEncoding
方法将在执行下面的
C#
代码时引发
NotSupportedException
:
*
* Encoding enc = Encoding.GetEncoding("shift-jis");
*
* **************************************************************/
//
从
base64String
中得到原始字符
return
ens.GetString(Convert.FromBase64String(base64String));
}
///
///
从
base64
编码的字符串中还原字符串,支持中文
///
///
base64
加密后的字符串
///
public
static
string
DecodingForString(
string
base64String)
{
return
DecodingForString(base64String, System.Text.Encoding.GetEncoding(
65001
));
}
//--------------------------------------------------------------------------------------
///
///
对任意类型的文件进行
base64
加码
///
///
文件的路径和文件名
///
public
static
string
EncodingForFile(
string
fileName)
{
System.IO.FileStream fs = System.IO.File.OpenRead(fileName);
System.IO.BinaryReader br =
new
System.IO.BinaryReader(fs);
/*System.Byte[] b=new System.Byte[fs.Length];
fs.Read(b,0,Convert.ToInt32(fs.Length));*/
string
base64String = Convert.ToBase64String(br.ReadBytes((
int
)fs.Length));
br.Close();
fs.Close();
return
base64String;
}
///
///
把经过
base64
编码的字符串保存为文件
///
///
经
base64
加码后的字符串
///
保存文件的路径和文件名
///
public
static
bool
SaveDecodingToFile(
string
base64String,
string
fileName)
{
System.IO.FileStream fs =
new
System.IO.FileStream(fileName, System.IO.FileMode.Create);
System.IO.BinaryWriter bw =
new
System.IO.BinaryWriter(fs);
bw.Write(Convert.FromBase64String(base64String));
bw.Close();
fs.Close();
return
true
;
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26442936/viewspace-736092/ ,如需转载,请注明出处,否则将追究法律责任。