ITPub博客

首页 > 数据库 > Oracle > Oracle 10g 运维之开发 数据乱码(之.net加密)

Oracle 10g 运维之开发 数据乱码(之.net加密)

原创 Oracle 作者:lovehewenyu 时间:2012-07-20 09:10:31 0 删除 编辑

数据乱码(之 .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 加码  
///  
 
///   文件的路径和文件名  
///   对文件进行 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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
10年金融行业老鸟。Oracle,Mysql,PostgreSQL,EMC 存储,NBU备份。微信/电话 18211103995

注册时间:2012-02-03

  • 博文量
    307
  • 访问量
    1528464