厚积薄发,丰富的公用类库积累,助你高效进行系统开发(8)----非对称加密、BASE64加密、MD5等常用加密处理
俗话说,一个好汉十个帮,众人拾柴火焰高等都说明一个道理,有更多的资源,更丰富的积累,都是助你走向成功,走向顶峰的推动力。 本篇继续继续整理优化已有的共用类库,并继续发表随笔介绍公用类库的接口方法以及详细使用操作,力求给自己继续优化,积攒更丰富的公用类库资源,加深了解的同时,也给大家展现公用类库好的方面。 本篇的公用类库的介绍主题是加密解密的部分,加解密算法包括DES加解密、Base64加解密、
AES RijndaelManaged加解密、MD5加密、以及RSA非对称加密等操作
。如果你对前面的类库介绍文章有兴趣,可以参考下面的连接了解。
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(7)
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(6)
本人开发过很多共享软件,在共享软件注册方面积累了一些自己的经验,其中采用非对称加密方式实现注册码验证的操作,就是其中一个比较重要的步骤,由于其逻辑不可逆的特点,采用非对称加密方式,较一般的对称加密方式,能够隐藏授权的逻辑,因此具有更好的效果。 这个非对称的解密解密、验证操作,是我所有共享软件里面用到的授权操作,很早很多朋友就这个问题问过我很多次,现在奉献给大家注册码实现的思路及操作接口,希望大家能够在享受代码带来的便利外,也可以提高自己对知识产权的保护。
一般来说,非对称加密方式,结合代码混淆和强名称验证,是比较好的实现注册授权机制的功能。
<summary>
///
非对称加密生成的私钥和公钥
///
</summary>
///
<param name="privateKey">
私钥
</param>
///
<param name="publicKey">
公钥
</param>
public
static
void
GenerateRSAKey(
out
string
privateKey,
out
string
publicKey)
#region
非对称数据加密(公钥加密)
///
<summary>
///
非对称加密字符串数据,返回加密后的数据
///
</summary>
///
<param name="publicKey">
公钥
</param>
///
<param name="originalString">
待加密的字符串
</param>
///
<returns>
加密后的数据
</returns>
public
static
string
RSAEncrypt(
string
publicKey,
string
originalString)
///
<summary>
///
非对称加密字节数组,返回加密后的数据
///
</summary>
///
<param name="publicKey">
公钥
</param>
///
<param name="originalBytes">
待加密的字节数组
</param>
///
<returns>
返回加密后的数据
</returns>
public
static
string
RSAEncrypt(
string
publicKey,
byte
[] originalBytes)
#endregion
#region
非对称解密(私钥解密)
///
<summary>
///
非对称解密字符串,返回解密后的数据
///
</summary>
///
<param name="privateKey">
私钥
</param>
///
<param name="encryptedString">
待解密数据
</param>
///
<returns>
返回解密后的数据
</returns>
public
static
string
RSADecrypt(
string
privateKey,
string
encryptedString)
///
<summary>
///
非对称解密字节数组,返回解密后的数据
///
</summary>
///
<param name="privateKey">
私钥
</param>
///
<param name="encryptedBytes">
待解密数据
</param>
///
<returns></returns>
public
static
string
RSADecrypt(
string
privateKey,
byte
[] encryptedBytes)
#endregion
#region
非对称加密签名、验证
///
<summary>
///
使用非对称加密签名数据
///
</summary>
///
<param name="privateKey">
私钥
</param>
///
<param name="originalString">
待加密的字符串
</param>
///
<returns>
加密后的数据
</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
生成加解密私钥、公钥
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>
如果用户已经注册, 那么返回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>
///
调用非对称加密方式对序列号进行验证
///
</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
<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>
///
加密数据文件,注意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>
///
解密数据文件,注意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>
加密结果字符串
</returns>
public
static
string
AES_Encrypt(
string
encryptString)
///
<summary>
///
对称加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是块式加密算法)
///
</summary>
///
<param name="encryptString">
待加密字符串
</param>
///
<param name="encryptKey">
加密密钥,须半角字符
</param>
///
<returns>
加密结果字符串
</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基的位置計數法。它使用2的最大次方來代表僅可列印的ASCII 字元。
///
這使它可用來作為電子郵件的傳輸編碼。在Base64中的變數使用字元A-Z、a-z和0-9 ,
///
這樣共有62個字元,用來作為開始的64個數字,最後兩個用來作為數字的符號在不同的
///
系統中而不同。
///
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. 验证码转为大写
///
2. 将密码使用这个方法进行三次加密后,与验证码进行叠加
///
3. 然后将叠加后的内容再次MD5一下,得到最终验证码的值
///
</summary>
///
<param name="s"></param>
///
<returns></returns>
public
static
string
EncyptMD5_3_16(
string
s)
#endregion
///
<summary>
///
SHA256函数
///
</summary>
///
<param name="str">
原始字符串
</param>
///
<returns>
SHA256结果(返回长度为44字节的字符串)
</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)
<summary>
///
对字符串加密
///
</summary>
///
<returns></returns>
private
string
EncodePassword(
string
passwordText)
{
return
EncodeHelper.MD5Encrypt(passwordText);
}
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);
3、 MD5各种长度加密字符、验证MD5等操作辅助类 MD5Util
<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>
是否加了标签或是否标签值与内容值一致
</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);
<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()
void
btnBase64_Click(
object
sender, EventArgs e)
{
string
original =
"
这是一个测试的Base64加密字符串
"
;
string
encrypt = Base64Util.Encrypt(original);
Console.WriteLine(encrypt);
//
输出内容:6L*Z5pi_5LiA5Liq5rWL6K*V55qEQmFzZTY05Yqg5b*G5b2X56ym5Liy
string
decrypt = Base64Util.Decrypt(encrypt);
Debug.Assert(original == decrypt);
//
验证相等
}
2)在QQ的很多模拟网页采集数据,需要输入用户账号、密码,其中密码是需要进行加密操作的,一般使用js脚本实现,这里把它转化为C#的代码操作,其实也就是把密码和验证码通过3次MD5加密实现的。
<summary>
///
QQ根据密码及验证码对数据进行加密
///
</summary>
///
<param name="password">
原始密码
</param>
///
<param name="verifyCode">
验证码
</param>
///
<returns></returns>
static
string
EncodePasswordWithVerifyCode(
string
password,
string
verifyCode)
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;
}
http://www.iqidi.com/download/commonshelp.rar
最新公用类库DLL+XML注释文件下载地址是:
https://files.cnblogs.com/wuhuacong/WHC.OrderWater.Commons.rar