資料亂碼(之.net加密)

lovehewenyu發表於2012-07-20

資料亂碼(之.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 字串從ZHS16GBKUTF8字符集(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              {
                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              {
                string[] str2 = strs[i].Split('.');
                if (str2[2].Contains("->"))
                {
                    string[] str3 = str2[2].Split('@');
                    for (int j = 0; 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#中的charstring由於採用了unicode編碼,就不能按照上面的公式計算了 
    * ansi
的位元組編和unicode編碼不相容 
    * 
故利用.net類庫提供的編碼類實現從ansi編碼到unicode程式碼的轉換 
    * 
    * GetEncoding 
方法依賴於基礎平臺支援大部分內碼表。但是,對於下列情況提供系統支援:預設編碼,即在執行此方法的計算機的區域設定中指定的編碼;Little-Endian Unicode (UTF-16LE)Big-Endian Unicode (UTF-16BE)Windows 作業系統 (windows-1252)UTF-7UTF-8ASCII 以及 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部落格 ” ,連結:http://blog.itpub.net/26442936/viewspace-736092/,如需轉載,請註明出處,否則將追究法律責任。

相關文章