俗話說,一個好漢十個幫,眾人拾柴火焰高等都說明一個道理,有更多的資源,更豐富的積累,都是助你走向成功,走向頂峰的推動力。
本篇繼續(xù)繼續(xù)整理優(yōu)化已有的共用類庫,并繼續(xù)發(fā)表隨筆介紹公用類庫的接口方法以及詳細使用操作,力求給自己繼續(xù)優(yōu)化,積攢更豐富的公用類庫資源,加深了解的同時,也給大家展現(xiàn)公用類庫好的方面。
本篇的公用類庫的介紹主題是加密解密的部分,加解密算法包括DES加解密、Base64加解密、
AES RijndaelManaged加解密、MD5加密、以及RSA非對稱加密等操作。
1、非對稱加密、解密、驗證輔助類 RSASecurityHelper
本人開發(fā)過很多共享軟件,在共享軟件注冊方面積累了一些自己的經(jīng)驗,其中采用非對稱加密方式實現(xiàn)注冊碼驗證的操作,就是其中一個比較重要的步驟,由于其邏輯不可逆的特點,采用非對稱加密方式,較一般的對稱加密方式,能夠隱藏授權(quán)的邏輯,因此具有更好的效果。 這個非對稱的解密解密、驗證操作,是我所有共享軟件里面用到的授權(quán)操作,很早很多朋友就這個問題問過我很多次,現(xiàn)在奉獻給大家注冊碼實現(xiàn)的思路及操作接口,希望大家能夠在享受代碼帶來的便利外,也可以提高自己對知識產(chǎn)權(quán)的保護。
一般來說,非對稱加密方式,結(jié)合代碼混淆和強名稱驗證,是比較好的實現(xiàn)注冊授權(quán)機制的功能。
**實現(xiàn)效果 **
1)本輔助類主要是用來方便實現(xiàn)非對稱加密、解密、驗證等相關(guān)操作。
2)非對稱加密有RSA、橢圓曲線等,最流行的是RSA。所謂的非對稱,是因為它有兩個密鑰,一個稱為公鑰,一個稱為私鑰。公鑰是可以對外發(fā)布的,而私鑰是自己保存的。用公鑰加密,必須用私鑰解密,反之,用私鑰加密必須用公鑰解密。所以,我們可以在軟件中保存公鑰的內(nèi)容,這個是可以公開的;私鑰我們可以自己留著。別人拿不到私鑰,根本計算不出注冊碼來。
3)使用輔助類RSASecurityHelper實現(xiàn)注冊機制如下:
a. 注冊碼產(chǎn)生過程:
注冊信息(包括用戶名等信息)---> RSA私鑰加密 ---> 注冊碼。
b. 軟件驗證注冊碼過程:
注冊碼 ---> RSA公鑰驗證 ---> 驗證成功或失敗。


**實現(xiàn)代碼 **
1)輔助類提供的方法接口如下所示:
/// <summary>
/// 非對稱加密生成的私鑰和公鑰
/// </summary>
/// <param name="privateKey">私鑰</param>
/// <param name="publicKey">公鑰</param>
public static void GenerateRSAKey(out string privateKey, out string publicKey)
#region 非對稱數(shù)據(jù)加密(公鑰加密)
/// <summary>
/// 非對稱加密字符串數(shù)據(jù),返回加密后的數(shù)據(jù)
/// </summary>
/// <param name="publicKey">公鑰</param>
/// <param name="originalString">待加密的字符串</param>
/// <returns>加密后的數(shù)據(jù)</returns>
public static string RSAEncrypt(string publicKey, string originalString)
/// <summary>
/// 非對稱加密字節(jié)數(shù)組,返回加密后的數(shù)據(jù)
/// </summary>
/// <param name="publicKey">公鑰</param>
/// <param name="originalBytes">待加密的字節(jié)數(shù)組</param>
/// <returns>返回加密后的數(shù)據(jù)</returns>
public static string RSAEncrypt(string publicKey, byte[] originalBytes)
#endregion
#region 非對稱解密(私鑰解密)
/// <summary>
/// 非對稱解密字符串,返回解密后的數(shù)據(jù)
/// </summary>
/// <param name="privateKey">私鑰</param>
/// <param name="encryptedString">待解密數(shù)據(jù)</param>
/// <returns>返回解密后的數(shù)據(jù)</returns>
public static string RSADecrypt(string privateKey, string encryptedString)
/// <summary>
/// 非對稱解密字節(jié)數(shù)組,返回解密后的數(shù)據(jù)
/// </summary>
/// <param name="privateKey">私鑰</param>
/// <param name="encryptedBytes">待解密數(shù)據(jù)</param>
/// <returns></returns>
public static string RSADecrypt(string privateKey, byte[] encryptedBytes)
#endregion
#region 非對稱加密簽名、驗證
/// <summary>
/// 使用非對稱加密簽名數(shù)據(jù)
/// </summary>
/// <param name="privateKey">私鑰</param>
/// <param name="originalString">待加密的字符串</param>
/// <returns>加密后的數(shù)據(jù)</returns>
public static string RSAEncrypSignature(string privateKey, string originalString)
/// <summary>
/// 對私鑰加密簽名的字符串,使用公鑰對其進行驗證
/// </summary>
/// <param name="originalString">未加密的文本,如機器碼</param>
/// <param name="encrytedString">加密后的文本,如注冊序列號</param>
/// <returns>如果驗證成功返回True,否則為False</returns>
public static bool Validate(string originalString, string encrytedString)
/// <summary>
/// 對私鑰加密的字符串,使用公鑰對其進行驗證
/// </summary>
/// <param name="originalString">未加密的文本,如機器碼</param>
/// <param name="encrytedString">加密后的文本,如注冊序列號</param>
/// <param name="publicKey">非對稱加密的公鑰</param>
/// <returns>如果驗證成功返回True,否則為False</returns>
public static bool Validate(string originalString, string encrytedString, string publicKey)
#endregion
2) 輔助類RSASecurityHelper的使用例子代碼如下所示
//生成加解密私鑰、公鑰
string publicKey = "";
string privateKey = "";
RSASecurityHelper.GenerateRSAKey(out privateKey, out publicKey);
string originalString = "testdata";
string encryptedString = RSASecurityHelper.RSAEncrypt(publicKey, originalString);
string originalString2 = RSASecurityHelper.RSADecrypt(privateKey, encryptedString);
if (originalString == originalString2)
{
MessageUtil.ShowTips("解密完全正確");
}
else
{
MessageUtil.ShowWarning("解密失敗");
}
string regcode = RSASecurityHelper.RSAEncrypSignature(privateKey, originalString);
bool validated = RSASecurityHelper.Validate(originalString, regcode, publicKey);
MessageUtil.ShowTips( validated ? "驗證成功" : "驗證失敗");
3)實際項目使用的注冊驗證代碼如下所示。
/// <summary>
/// 每次程序運行時候,檢查用戶是否注冊
/// </summary>
/// <returns>如果用戶已經(jīng)注冊, 那么返回True, 否則為False</returns>
public bool CheckRegister()
{
// 先獲取用戶的注冊碼進行比較
string serialNumber = string.Empty; //注冊碼
RegistryKey reg = Registry.CurrentUser.OpenSubKey(UIConstants.SoftwareRegistryKey, true);
if (null != reg)
{
serialNumber = (string)reg.GetValue("SerialNumber");
Portal.gc.bRegisted = Portal.gc.Register(serialNumber);
}
return Portal.gc.bRegisted;
}
/// <summary>
/// 調(diào)用非對稱加密方式對序列號進行驗證
/// </summary>
/// <param name="serialNumber">正確的序列號</param>
/// <returns>如果成功返回True,否則為False</returns>
public bool Register(String serialNumber)
{
string hardNumber = HardwareInfoHelper.GetCPUId();
return RSASecurityHelper.Validate(hardNumber, serialNumber);
}
public string GetHardNumber()
{
return HardwareInfoHelper.GetCPUId();
}
**2、**** DES對稱加解密、AES RijndaelManaged加解密、Base64加密解密、MD5加密等操作輔助類 EncodeHelper **
**實現(xiàn)效果 **
1)本輔助類主要是用來方便實現(xiàn)DES對稱加解密、AES RijndaelManaged加解密、Base64加密解密、MD5加密等操作。
2)本輔助類實現(xiàn)多種加解密處理,可以實現(xiàn)字符串、文件、文件流等加密處理。該加密輔助類匯集各種加密處理邏輯,是一個非常常用、方便應(yīng)對各種加密處理的輔助類。
**實現(xiàn)代碼 **
1)輔助類提供的方法接口如下所示:
/// <summary>
/// 使用默認加密
/// </summary>
/// <param name="strText"></param>
/// <returns></returns>
public static string DesEncrypt(string strText)
/// <summary>
/// 使用默認解密
/// </summary>
/// <param name="strText">解密字符串</param>
/// <returns></returns>
public static string DesDecrypt(string strText)
/// <summary>
/// 加密字符串,注意strEncrKey的長度為8位
/// </summary>
/// <param name="strText">待加密字符串</param>
/// <param name="strEncrKey">加密鍵</param>
/// <returns></returns>
public static string DesEncrypt(string strText, string strEncrKey)
/// <summary>
/// 解密字符串,注意strEncrKey的長度為8位
/// </summary>
/// <param name="strText">待解密的字符串</param>
/// <param name="sDecrKey">解密鍵</param>
/// <returns>解密后的字符串</returns>
public static string DesDecrypt(string strText, string sDecrKey)
/// <summary>
/// 加密數(shù)據(jù)文件,注意strEncrKey的長度為8位
/// </summary>
/// <param name="m_InFilePath">待加密的文件路徑</param>
/// <param name="m_OutFilePath">輸出文件路徑</param>
/// <param name="strEncrKey">加密鍵</param>
public static void DesEncrypt(string m_InFilePath, string m_OutFilePath, string strEncrKey)
/// <summary>
/// 解密數(shù)據(jù)文件,注意strEncrKey的長度為8位
/// </summary>
/// <param name="m_InFilePath">待解密的文件路徑</param>
/// <param name="m_OutFilePath">輸出路徑</param>
/// <param name="sDecrKey">解密鍵</param>
public static void DesDecrypt(string m_InFilePath, string m_OutFilePath, string sDecrKey)
#endregion
#region 對稱加密算法AES RijndaelManaged加密解密
/// <summary>
/// 對稱加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是塊式加密算法)
/// </summary>
/// <param name="encryptString">待加密字符串</param>
/// <returns>加密結(jié)果字符串</returns>
public static string AES_Encrypt(string encryptString)
/// <summary>
/// 對稱加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是塊式加密算法)
/// </summary>
/// <param name="encryptString">待加密字符串</param>
/// <param name="encryptKey">加密密鑰,須半角字符</param>
/// <returns>加密結(jié)果字符串</returns>
public static string AES_Encrypt(string encryptString, string encryptKey)
/// <summary>
/// 對稱加密算法AES RijndaelManaged解密字符串
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <returns>解密成功返回解密后的字符串,失敗返源串</returns>
public static string AES_Decrypt(string decryptString)
/// <summary>
/// 對稱加密算法AES RijndaelManaged解密字符串
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密鑰,和加密密鑰相同</param>
/// <returns>解密成功返回解密后的字符串,失敗返回空</returns>
public static string AES_Decrypt(string decryptString, string decryptKey)
/// <summary>
/// 加密文件流
/// </summary>
/// <param name="fs">文件流</param>
/// <returns></returns>
public static CryptoStream AES_EncryptStrream(FileStream fs, string decryptKey)
/// <summary>
/// 解密文件流
/// </summary>
/// <param name="fs">文件流</param>
/// <returns></returns>
public static CryptoStream AES_DecryptStream(FileStream fs, string decryptKey)
/// <summary>
/// 對指定文件加密
/// </summary>
/// <param name="InputFile">輸入文件</param>
/// <param name="OutputFile">輸出文件</param>
/// <returns></returns>
public static bool AES_EncryptFile(string InputFile, string OutputFile)
/// <summary>
/// 對指定的文件解壓縮
/// </summary>
/// <param name="InputFile">輸入文件</param>
/// <param name="OutputFile">輸出文件</param>
/// <returns></returns>
public static bool AES_DecryptFile(string InputFile, string OutputFile)
#endregion
#region Base64加密解密
/// <summary>
/// Base64是一種使用64基的位置計數(shù)法。它使用2的最大次方來代表僅可列印的ASCII 字元。
/// 這使它可用來作為電子郵件的傳輸編碼。在Base64中的變數(shù)使用字元A-Z、a-z和0-9 ,
/// 這樣共有62個字元,用來作為開始的64個數(shù)字,最後兩個用來作為數(shù)字的符號在不同的
/// 系統(tǒng)中而不同。
/// Base64加密
/// </summary>
/// <param name="str">Base64方式加密字符串</param>
/// <returns></returns>
public static string Base64Encrypt(string str)
/// <summary>
/// Base64解密字符串
/// </summary>
/// <param name="str">待解密的字符串</param>
/// <returns></returns>
public static string Base64Decrypt(string str)
#endregion
#region MD5加密
/// <summary>
/// 使用MD5加密字符串
/// </summary>
/// <param name="strText">待加密的字符串</param>
/// <returns>MD5加密后的字符串</returns>
public static string MD5Encrypt(string strText)
/// <summary>
/// 使用MD5加密的Hash表
/// </summary>
/// <param name="input">待加密字符串</param>
/// <returns></returns>
public static string MD5EncryptHash(String input)
/// <summary>
/// 使用Md5加密為16進制字符串
/// </summary>
/// <param name="input">待加密字符串</param>
/// <returns></returns>
public static string MD5EncryptHashHex(String input)
/// <summary>
/// MD5 三次加密算法.計算過程: (QQ使用)
/// 1. 驗證碼轉(zhuǎn)為大寫
/// 2. 將密碼使用這個方法進行三次加密后,與驗證碼進行疊加
/// 3. 然后將疊加后的內(nèi)容再次MD5一下,得到最終驗證碼的值
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string EncyptMD5_3_16(string s)
#endregion
/// <summary>
/// SHA256函數(shù)
/// </summary>
/// <param name="str">原始字符串</param>
/// <returns>SHA256結(jié)果(返回長度為44字節(jié)的字符串)</returns>
public static string SHA256(string str)
/// <summary>
/// 加密字符串(使用MD5+Base64混合加密)
/// </summary>
/// <param name="input">待加密的字符串</param>
/// <returns></returns>
public static string EncryptString(string input)
/// <summary>
/// 解密加過密的字符串(使用MD5+Base64混合加密)
/// </summary>
/// <param name="input">待解密的字符串</param>
/// <param name="throwException">解密失敗是否拋異常</param>
/// <returns></returns>
public static string DecryptString(string input, bool throwException)
2) 輔助類EncodeHelper的使用例子代碼如下所示
/// <summary>
/// 對字符串加密
/// </summary>
/// <returns></returns>
private string EncodePassword(string passwordText)
{
return EncodeHelper.MD5Encrypt(passwordText);
}
private void btnEncrypt_Click(object sender, EventArgs e)
{
string original = "測試加密字符串";
Console.WriteLine("original:" + original);
string encrypt = EncodeHelper.SHA256(original);
Console.WriteLine("EncodeHelper.SHA256" + encrypt);
//DES加解密
encrypt = EncodeHelper.DesEncrypt(original);
Console.WriteLine("EncodeHelper.DesEncrypt:" + encrypt);
string decrypt = EncodeHelper.DesDecrypt(encrypt);
Console.WriteLine("EncodeHelper.DesDecrypt:" + decrypt);
//MD5加密
encrypt = EncodeHelper.MD5Encrypt(original);
Console.WriteLine("EncodeHelper.MD5Encrypt:" + encrypt);
encrypt = EncodeHelper.MD5EncryptHash(original);
Console.WriteLine("EncodeHelper.MD5EncryptHash:" + encrypt);
encrypt = EncodeHelper.MD5EncryptHashHex(original);
Console.WriteLine("EncodeHelper.MD5EncryptHashHex" + encrypt);
encrypt = EncodeHelper.EncyptMD5_3_16(original);
Console.WriteLine("EncodeHelper.EncyptMD5_3_16:" + encrypt);
//Base64加解密
encrypt = EncodeHelper.Base64Encrypt(original);
Console.WriteLine("EncodeHelper.Base64Encrypt" + encrypt);
decrypt = EncodeHelper.Base64Encrypt(encrypt);
Console.WriteLine("EncodeHelper.Base64Encrypt" + decrypt);
encrypt = EncodeHelper.AES_Encrypt(original);
Console.WriteLine("EncodeHelper.AES_Encrypt" + encrypt);
decrypt = EncodeHelper.AES_Decrypt(encrypt);
Console.WriteLine("EncodeHelper.AES_Decrypt" + decrypt); c

**3、 MD5各種長度加密字符、驗證MD5等操作輔助類 MD5Util **
**實現(xiàn)效果 **
1)本輔助類主要是用來方便實現(xiàn)MD5各種長度加密字符、驗證MD5等操作。
2)MD5即Message-Digest Algorithm 5(信息-摘要算法 5),用于確保信息傳輸完整一致。是計算機廣泛使用的散列算法之一(又譯摘要算法、哈希算法)。
3)MD5已經(jīng)廣泛使用在為文件傳輸提供一定的可靠性方面。例如,服務(wù)器預(yù)先提供一個MD5校驗和,用戶下載完文件以后,用MD5算法計算下載文件的MD5校驗和,然后通過檢查這兩個校驗和是否一致,就能判斷下載的文件是否出錯
**實現(xiàn)代碼 **
1)輔助類提供的方法接口如下所示:
/// <summary>
/// 獲得32位的MD5加密
/// </summary>
public static string GetMD5_32(string input)
/// <summary>
/// 獲得16位的MD5加密
/// </summary>
public static string GetMD5_16(string input)
/// <summary>
/// 獲得8位的MD5加密
/// </summary>
public static string GetMD5_8(string input)
/// <summary>
/// 獲得4位的MD5加密
/// </summary>
public static string GetMD5_4(string input)
/// <summary>
/// 添加MD5的前綴,便于檢查有無篡改
/// </summary>
public static string AddMD5Profix(string input)
/// <summary>
/// 移除MD5的前綴
/// </summary>
public static string RemoveMD5Profix(string input)
/// <summary>
/// 驗證MD5前綴處理的字符串有無被篡改
/// </summary>
public static bool ValidateValue(string input)
#region MD5簽名驗證
/// <summary>
/// 對給定文件路徑的文件加上標簽
/// </summary>
/// <param name="path">要加密的文件的路徑</param>
/// <returns>標簽的值</returns>
public static bool AddMD5(string path)
/// <summary>
/// 對給定路徑的文件進行驗證,如果一致返回True,否則返回False
/// </summary>
/// <param name="path"></param>
/// <returns>是否加了標簽或是否標簽值與內(nèi)容值一致</returns>
public static bool CheckMD5(string path)
2) 輔助類 **MD5Util **的使用例子代碼如下所示
//為文件增加MD5編碼標簽,然后驗證是否被修改
string file = @"c:\test.xls";
bool flag2 = MD5Util.AddMD5(file);
Console.WriteLine(flag2);
//對給定路徑的文件進行驗證,如果一致返回True,否則返回False
bool flag3 = MD5Util.CheckMD5(file);
Console.WriteLine(flag3);
4、基于Base64的加密編碼輔助類 Base64Util
**實現(xiàn)效果 **
1)本輔助類主要是用來方便實現(xiàn)基于Base64的加密編碼。
2)Base64被定義為:Base64內(nèi)容傳送編碼被設(shè)計用來把任意序列的8位字節(jié)描述為一種不易被人直接識別的形式。Base64編碼一般在電子郵件中可以查看到,打開一封Email,查看其原始信息(您可以通過收取、導(dǎo)出該郵件用文本編輯器查看)。加密是肯定的,但是加密的目的不是讓用戶發(fā)送非常安全的Email。這種加密方式主要就是“防君子不防小人”。即達到一眼望去完全看不出內(nèi)容即可。
3)采用Base64編碼不僅比較簡短,同時也具有不可讀性,即所編碼的數(shù)據(jù)不會被人用肉眼所直接看到。
**實現(xiàn)代碼 **
1)輔助類提供的方法接口如下所示:
/// <summary>
/// 使用默認的密碼表加密字符串
/// </summary>
/// <param name="input">待加密字符串</param>
/// <returns></returns>
public static string Encrypt(string input)
/// <summary>
/// 使用默認的密碼表解密字符串
/// </summary>
/// <param name="input">待解密字符串</param>
/// <returns></returns>
public static string Decrypt(string input)
/// <summary>
/// 獲取具有標準的Base64密碼表的加密類
/// </summary>
/// <returns></returns>
public static Base64Util GetStandardBase64()
2) 輔助類Base64Util的使用例子代碼如下所示
private void btnBase64_Click(object sender, EventArgs e)
{
string original = "這是一個測試的Base64加密字符串";
string encrypt = Base64Util.Encrypt(original);
Console.WriteLine(encrypt);//輸出內(nèi)容:6L*Z5pi_5LiA5Liq5rWL6K*V55qEQmFzZTY05Yqg5b*G5b2X56ym5Liy
string decrypt = Base64Util.Decrypt(encrypt);
Debug.Assert(original == decrypt);//驗證相等
} c
5、QQ密碼加密操作輔助類 QQEncryptUtil
**實現(xiàn)效果 **
1)本輔助類主要是用來方便實現(xiàn)QQ密碼加密操作。 2)在QQ的很多模擬網(wǎng)頁采集數(shù)據(jù),需要輸入用戶賬號、密碼,其中密碼是需要進行加密操作的,一般使用js腳本實現(xiàn),這里把它轉(zhuǎn)化為C#的代碼操作,其實也就是把密碼和驗證碼通過3次MD5加密實現(xiàn)的。

**實現(xiàn)代碼 **
1)輔助類提供的方法接口如下所示:
/// <summary>
/// QQ根據(jù)密碼及驗證碼對數(shù)據(jù)進行加密
/// </summary>
/// <param name="password">原始密碼</param>
/// <param name="verifyCode">驗證碼</param>
/// <returns></returns>
public static string EncodePasswordWithVerifyCode(string password, string verifyCode)
2) 輔助類QQEncryptUtil的使用例子代碼如下所示
private bool CheckLogin()
{
HttpHelper httpHelper = new HttpHelper();
string refUrl = "http://ui.ptlogin2.qq.com/cgi-bin/login?appid=3000801&s_url=http%3A%2F%2Fqun.qq.com%2Fgod%2Fsucc.htm&f_url=loginerroralert&lang=2052&bgcolor=ffffff&style=1&low_login=1&link_target=blank&target=self&hide_title_bar=1&dummy=1";
string verifyCode = this.txtVerify.Text;
string postData = string.Format("u={0}&p={1}&verifycode={2}&aid=3000801&u1=http%3A%2F%2Fqun.qq.com%2Fgod%2Fsucc.htm&h=1&ptredirect=0&ptlang=2052&from_ui=1&dumy=&fp=loginerroralert",
this.txtUsername.Text, QQEncryptUtil.EncodePasswordWithVerifyCode(this.txtPassword.Text, verifyCode), verifyCode);
string result = httpHelper.GetHtml("http://ptlogin2.qq.com/login?" + postData, Portal.gc.cookieQun, refUrl);
string errorTxt = result;
bool isLogin = result.Contains("登錄成功!");
return isLogin;
}
CHM幫助文檔持續(xù)更新中,統(tǒng)一下載地址是: http://www.iqidi.com/download/commonshelp.rar