使用Aes对称加密解密Web.Config数据库连接串
现在很多公司开始为了保证数据库的安全性,通常会对Web.Config的数据库连接字符串进行加密。本文将介绍学习使用Aes加密解密数据库连接字符串。本文采用MySql数据库。
- AES概念简述
AES 是对称的高级加密标准算法(PS:对称加密就是加密用的密码和解密用的密码是一样的,非对称就是加密和解密用的密钥不一样)。
参考步骤:
1、Aes加密、解密工具
2、配置Web.Config
3、自定义数据库连接类
4、Aes加密、解密类
- Aes加密、解密工具
对数据库连接字符串进行加密,大家也可以使用在线的加密解密工具方式。
下图中"hema"为秘钥(Key)。
- 配置Web.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="Hema.Dao.CustomMySqlConnectionFactory, Hema.Dao" >
<parameters>
//数据Aes加密串
<parameter value="KrwK655bTg0YL0OYBllvwYM+BY6ioLMkizpMQEBL/VPB4gi0O1R15DR+BDfvCc0wOCgo+5/amzDz5bT7+On6rn5MPBIRFh5UTSOYgprJsdNCBrWOU7JfssLGpJOP3PJg" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
</providers>
</entityFramework>
</configuration>
<defaultConnectionFactory>项只会在没有添加connectionString配置项的情况下使用,默认值是LocalDbConnectionFactory,也就是使用LocalDb。我们可以将type改为"Hema.Dao.CustomMySqlConnectionFactory, Hema.Dao",这样就可以使用自定义类连接MySql数据库。
- 自定义数据库连接类
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);
}
}
}
- Aes加密、解密类
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
/// <summary>
/// AES加密
/// </summary>
/// <param name="encryptString">要加密的字符</param>
/// <param name="encryptKey">对应的密钥(不可为中文,不能超过32个字符,超过32个字符的截取前32个字符)</param>
/// <returns>返回Base64格式的字符串</returns>
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 }
}
使用Aes对称加密解密Web.Config数据库连接串的更多相关文章
- AES对称加密解密类
import java.io.UnsupportedEncodingException; import javax.crypto.Cipher; import javax.crypto.spec.Se ...
- 加密,解密web.config数据库连接字符串
"connectionStrings" 路径是web.config所在的工程目录. 1.加密EncryptWebConfig.bat @echo offC:\Windows\Mic ...
- aspnet_regiis 加密/解密 web.config
加密: @echo off echo web.config c: cd c:\windows\Microsoft.NET\Framework64\v4.0.30319 aspnet_regiis -p ...
- (译)利用ASP.NET加密和解密Web.config中连接字符串
介绍 这篇文章我将介绍如何利用ASP.NET来加密和解密Web.config中连接字符串 背景描述 在以前的博客中,我写了许多关于介绍 Asp.net, Gridview, SQL Server, A ...
- 利用ASP.NET加密和解密Web.config中连接字符串
摘自:博客园 介绍 这篇文章我将介绍如何利用ASP.NET来加密和解密Web.config中连接字符串 背景描述 在以前的博客中,我写了许多关于介绍 Asp.net, Gridview, SQL Se ...
- AES对称加密和解密(转)
AES对称加密和解密 package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingExce ...
- JAVA中AES对称加密和解密
AES对称加密和解密 package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingExce ...
- PHP 服务端 和 APP 客户端 实现 RSA+AES 双向加密解密
目的:服务端和移动端双向加密解密 共有七个文件 其中包括三个类文件 lib_aes.php aes对称加密解密类 server_rsa_crypt.php 服务端RSA公钥私钥非对称加密解密类 cli ...
- 命令行工具aspnet_regiis.exe实现加密和解密web.config
命令行工具aspnet_regiis.exe,是一个类似于DOS的命令工具,称之为命令解释器.使用命令行工具加密和解密web.config文件中的数据库连接字符串时,只需要简单的语法命令即可. 加密语 ...
随机推荐
- AngularJS1.X学习笔记10-自定义指令(下)
继续继续,学完这个部分就去吃饭.引用自由男人的话作为本文的开始:“默认情况下,链接函数被传入了控制器的作用域,而该控制器管理着的视图包含了指令所应用到的元素”.果然像是绕口令,还是看看你的例子比较好. ...
- 20道Java面试必考题
系统整理了一下有关Java的面试题,包括基础篇,javaweb篇,框架篇,数据库篇,多线程篇,并发篇,算法篇等等,陆续更新中.其他方面如前端后端等等的面试题也在整理中,都会有的. 注:文末有福利!pd ...
- Python内置函数(41)——id
英文文档: id(object) Return the "identity" of an object. This is an integer which is guarantee ...
- python网络爬虫与信息提取 学习笔记day1
Day1: 安装python之后,为其配置requests第三方库,并爬取百度主页内容. 语句解释: r.status_code检测请求的状态码,如果状态码为200,则说明访问成功,否则,则说明访问失 ...
- centos7配置Apache支持HTTPS
Apache版本2.4 安装mod_ssl yum install mod_ssl 建立文件夹,存放sslkey mkdir /etc/httpd/ssl/ 建立凭证档 openssl req -x5 ...
- Oracle:如何使用PL/SQL 11.0连接远程Oracle12c服务器?
背景: 如何实现远程连接服务器上的oracle12c? 1.安装一个oracle12c空库,使用oracle12c中集成的oracle pl/sql developer工具实现连接远程服务器上的ora ...
- python的调试
调试 程序能一次写完并正常执行的概率很小.总会有各种各样的bug需要修正. 有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时 哪些变量的值是正确的,哪些变量的值是错误的,因此 ...
- nginx 官方文档翻译
nginx(发音为"engine x")是一个由俄罗斯软件工程师Igor Sysoev编写的免费开源Web服务器.自2004年公开发布以来,nginx专注于高性能,高并发性和低内存 ...
- elasticsearch启动常见错误
问题出现环境,OS版本:CentOS-7-x86_64-Minimal-1708:ES版本:elasticsearch-6.2.2. 1.max file descriptors [4096] for ...
- springaop问题——Cannot subclass final class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages
问题描述: 在使用springaop对目标对象增强时,若切点的条件过于宽泛就会出现以下异常! 如: @Before("execution(* *(..))") @Before(&q ...