现在很多公司开始为了保证数据库的安全性,通常会对Web.Config的数据库连接字符串进行加密。本文将介绍学习使用Aes加密解密数据库连接字符串。本文采用MySql数据库。
AES 是对称的高级加密标准算法(PS:对称加密就是加密用的密码和解密用的密码是一样的,非对称就是加密和解密用的密钥不一样)。
参考步骤:
1、Aes加密、解密工具
2、配置Web.Config
3、自定义数据库连接类
4、Aes加密、解密类
对数据库连接字符串进行加密,大家也可以使用在线的加密解密工具方式。
下图中"hema"为秘钥(Key)。
using MySql.Data.Entity;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data.Entity.Core.Common;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hema.Framework.Core;
namespace Hema.Dao
{
//继承IDbConnectionFactory接口,此接口的实现用来基于给定的数据库名称创建某个数据库服务器类型的 DbConnection 对象。
public class CustomMySqlConnectionFactory : IDbConnectionFactory
{
public string _connectionString;
//秘钥
public const string Conn_EncryptKey = "hema";
public CustomMySqlConnectionFactory()
{
}
public CustomMySqlConnectionFactory(string connectionString)
{
//解密
\_connectionString = EncryptUtility.AESDecrypt(connectionString, Conn\_EncryptKey);
}
public System.Data.Common.DbConnection CreateConnection(string nameOrConnectionString)
{
//新建一个MySqlConnection数据库连接
return new MySqlConnection(\_connectionString);
}
}
}
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace Hema.Framework.Core
{
public class EncryptUtility
{
#region AES
///
/// 要加密的字符
/// 对应的密钥(不可为中文,不能超过32个字符,超过32个字符的截取前32个字符)
///
public static string AESEncrypt(string encryptString, string encryptKey, string vector = null)
{
if (string.IsNullOrEmpty(encryptString))
{
throw new ArgumentNullException("参数encryptString为空!");
}
if (string.IsNullOrEmpty(encryptKey))
{
throw new ArgumentNullException("参数encryptKey为空!");
}
if (encryptKey.Length > )
encryptKey = encryptKey.Substring(, );
if (encryptKey.Length < )
encryptKey = encryptKey.PadRight(, '');
RijndaelManaged rijndaelProvider = new RijndaelManaged();
rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey);
if (string.IsNullOrEmpty(vector))
{
rijndaelProvider.Mode = CipherMode.ECB;
}
else
{
rijndaelProvider.IV = Encoding.UTF8.GetBytes(vector);
}
rijndaelProvider.Padding = PaddingMode.PKCS7; // 填充模式
ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor();
byte\[\] inputData = Encoding.UTF8.GetBytes(encryptString);
byte\[\] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, , inputData.Length);
return Convert.ToBase64String(encryptedData);
}
/// <summary>
/// AES解密
/// </summary>
/// <param name="decryptString">要解密的字符(该字符必须是已经加密过的Base64格式的字符串)</param>
/// <param name="decryptKey">解密的密钥,该密钥要和加密的密钥一致(不可为中文,不能超过32个字符,超过32个字符的截取前32个字符)</param>
/// <returns>解密后的字符串</returns>
public static string AESDecrypt(string decryptString, string decryptKey, string vector = null)
{
if (string.IsNullOrEmpty(decryptString))
{
throw new ArgumentNullException("参数encryptString为空!");
}
if (string.IsNullOrEmpty(decryptKey))
{
throw new ArgumentNullException("参数encryptKey为空!");
}
if (decryptKey.Length > )
decryptKey = decryptKey.Substring(, );
if (decryptKey.Length < )
decryptKey = decryptKey.PadRight(, '');
try
{
RijndaelManaged rijndaelProvider = new RijndaelManaged();
rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);
if (string.IsNullOrEmpty(vector))
{
rijndaelProvider.Mode = CipherMode.ECB;
}
else
{
rijndaelProvider.IV = Encoding.UTF8.GetBytes(vector);
}
rijndaelProvider.Padding = PaddingMode.PKCS7; // 填充模式
ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor();
byte\[\] inputData = Convert.FromBase64String(decryptString);
byte\[\] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, , inputData.Length);
return Encoding.UTF8.GetString(decryptedData);
}
catch
{
return string.Empty;
}
}
/// <summary>
/// 加密文件流
/// </summary>
/// <param name="fs"></param>
/// <returns></returns>
public static CryptoStream AES\_EncryptStrream(FileStream fs, string decryptKey, string vector)
{
decryptKey = GetSubString(decryptKey, , "");
decryptKey = decryptKey.PadRight(, ' ');
RijndaelManaged rijndaelProvider = new RijndaelManaged();
rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);
rijndaelProvider.IV = Encoding.UTF8.GetBytes(vector);
ICryptoTransform encrypto = rijndaelProvider.CreateEncryptor();
CryptoStream cytptostreamEncr = new CryptoStream(fs, encrypto, CryptoStreamMode.Write);
return cytptostreamEncr;
}
/// <summary>
/// 解密文件流
/// </summary>
/// <param name="fs"></param>
/// <returns></returns>
public static CryptoStream AES\_DecryptStream(FileStream fs, string decryptKey, string vector)
{
decryptKey = GetSubString(decryptKey, , "");
decryptKey = decryptKey.PadRight(, ' ');
RijndaelManaged rijndaelProvider = new RijndaelManaged();
rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);
rijndaelProvider.IV = Encoding.UTF8.GetBytes(vector);
ICryptoTransform Decrypto = rijndaelProvider.CreateDecryptor();
CryptoStream cytptostreamDecr = new CryptoStream(fs, Decrypto, CryptoStreamMode.Read);
return cytptostreamDecr;
}
/// <summary>
/// 对指定文件加密
/// </summary>
/// <param name="InputFile"></param>
/// <param name="OutputFile"></param>
/// <returns></returns>
public static bool AES\_EncryptFile(string InputFile, string OutputFile, string vector)
{
try
{
string decryptKey = "www.iqidi.com";
FileStream fr = new FileStream(InputFile, FileMode.Open);
FileStream fren = new FileStream(OutputFile, FileMode.Create);
CryptoStream Enfr = AES\_EncryptStrream(fren, decryptKey, vector);
byte\[\] bytearrayinput = new byte\[fr.Length\];
fr.Read(bytearrayinput, , bytearrayinput.Length);
Enfr.Write(bytearrayinput, , bytearrayinput.Length);
Enfr.Close();
fr.Close();
fren.Close();
}
catch
{
//文件异常
return false;
}
return true;
}
/// <summary>
/// 对指定的文件解压缩
/// </summary>
/// <param name="InputFile"></param>
/// <param name="OutputFile"></param>
/// <returns></returns>
public static bool AES\_DecryptFile(string InputFile, string OutputFile, string vector)
{
try
{
string decryptKey = "www.iqidi.com";
FileStream fr = new FileStream(InputFile, FileMode.Open);
FileStream frde = new FileStream(OutputFile, FileMode.Create);
CryptoStream Defr = AES\_DecryptStream(fr, decryptKey, vector);
byte\[\] bytearrayoutput = new byte\[\];
int m\_count = ;
do
{
m\_count = Defr.Read(bytearrayoutput, , bytearrayoutput.Length);
frde.Write(bytearrayoutput, , m\_count);
if (m\_count < bytearrayoutput.Length)
break;
} while (true);
Defr.Close();
fr.Close();
frde.Close();
}
catch
{
//文件异常
return false;
}
return true;
}
/// <summary>
/// 按字节长度(按字节,一个汉字为2个字节)取得某字符串的一部分
/// </summary>
/// <param name="sourceString">源字符串</param>
/// <param name="length">所取字符串字节长度</param>
/// <param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,一般为"...")</param>
/// <returns>某字符串的一部分</returns>
private static string GetSubString(string sourceString, int length, string tailString)
{
return GetSubString(sourceString, , length, tailString);
}
/// <summary>
/// 按字节长度(按字节,一个汉字为2个字节)取得某字符串的一部分
/// </summary>
/// <param name="sourceString">源字符串</param>
/// <param name="startIndex">索引位置,以0开始</param>
/// <param name="length">所取字符串字节长度</param>
/// <param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,一般为"...")</param>
/// <returns>某字符串的一部分</returns>
private static string GetSubString(string sourceString, int startIndex, int length, string tailString)
{
string myResult = sourceString;
//当是日文或韩文时(注:中文的范围:\\u4e00 - \\u9fa5, 日文在\\u0800 - \\u4e00, 韩文为\\xAC00-\\xD7A3)
if (System.Text.RegularExpressions.Regex.IsMatch(sourceString, "\[\\u0800-\\u4e00\]+") ||
System.Text.RegularExpressions.Regex.IsMatch(sourceString, "\[\\xAC00-\\xD7A3\]+"))
{
//当截取的起始位置超出字段串长度时
if (startIndex >= sourceString.Length)
{
return string.Empty;
}
else
{
return sourceString.Substring(startIndex,
((length + startIndex) > sourceString.Length) ? (sourceString.Length - startIndex) : length);
}
}
//中文字符,如"中国人民abcd123"
if (length <= )
{
return string.Empty;
}
byte\[\] bytesSource = Encoding.Default.GetBytes(sourceString);
//当字符串长度大于起始位置
if (bytesSource.Length > startIndex)
{
int endIndex = bytesSource.Length;
//当要截取的长度在字符串的有效长度范围内
if (bytesSource.Length > (startIndex + length))
{
endIndex = length + startIndex;
}
else
{ //当不在有效范围内时,只取到字符串的结尾
length = bytesSource.Length - startIndex;
tailString = "";
}
int\[\] anResultFlag = new int\[length\];
int nFlag = ;
//字节大于127为双字节字符
for (int i = startIndex; i < endIndex; i++)
{
if (bytesSource\[i\] > )
{
nFlag++;
if (nFlag == )
{
nFlag = ;
}
}
else
{
nFlag = ;
}
anResultFlag\[i\] = nFlag;
}
//最后一个字节为双字节字符的一半
if ((bytesSource\[endIndex - \] > ) && (anResultFlag\[length - \] == ))
{
length = length + ;
}
byte\[\] bsResult = new byte\[length\];
Array.Copy(bytesSource, startIndex, bsResult, , length);
myResult = Encoding.Default.GetString(bsResult);
myResult = myResult + tailString;
return myResult;
}
return string.Empty;
}
#endregion
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章