现在很多公司开始为了保证数据库的安全性,通常会对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数据库连接串的更多相关文章

  1. AES对称加密解密类

    import java.io.UnsupportedEncodingException; import javax.crypto.Cipher; import javax.crypto.spec.Se ...

  2. 加密,解密web.config数据库连接字符串

    "connectionStrings" 路径是web.config所在的工程目录. 1.加密EncryptWebConfig.bat @echo offC:\Windows\Mic ...

  3. aspnet_regiis 加密/解密 web.config

    加密: @echo off echo web.config c: cd c:\windows\Microsoft.NET\Framework64\v4.0.30319 aspnet_regiis -p ...

  4. (译)利用ASP.NET加密和解密Web.config中连接字符串

    介绍 这篇文章我将介绍如何利用ASP.NET来加密和解密Web.config中连接字符串 背景描述 在以前的博客中,我写了许多关于介绍 Asp.net, Gridview, SQL Server, A ...

  5. 利用ASP.NET加密和解密Web.config中连接字符串

    摘自:博客园 介绍 这篇文章我将介绍如何利用ASP.NET来加密和解密Web.config中连接字符串 背景描述 在以前的博客中,我写了许多关于介绍 Asp.net, Gridview, SQL Se ...

  6. AES对称加密和解密(转)

    AES对称加密和解密 package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingExce ...

  7. JAVA中AES对称加密和解密

    AES对称加密和解密 package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingExce ...

  8. PHP 服务端 和 APP 客户端 实现 RSA+AES 双向加密解密

    目的:服务端和移动端双向加密解密 共有七个文件 其中包括三个类文件 lib_aes.php aes对称加密解密类 server_rsa_crypt.php 服务端RSA公钥私钥非对称加密解密类 cli ...

  9. 命令行工具aspnet_regiis.exe实现加密和解密web.config

    命令行工具aspnet_regiis.exe,是一个类似于DOS的命令工具,称之为命令解释器.使用命令行工具加密和解密web.config文件中的数据库连接字符串时,只需要简单的语法命令即可. 加密语 ...

随机推荐

  1. c 语言typedef 和 define的使用和区别

    #define是C的指令,用于为各种数据类型定义别名,与typedef 类似,但是有一下几点不同 1,typedef仅限于为类型定义符号名称,而#define不仅可以为类型定义符号名称,也能为数值定义 ...

  2. Python-模块使用-Day6

    Python 之路 Day6 - 常用模块学习 本节大纲: 模块介绍time &datetime模块randomossysshutiljson & picleshelvexml处理ya ...

  3. jquery-模仿qq提示消息

    ( function() { var ua = navigator.userAgent.toLowerCase(); var is = (ua.match(/\b(chrome|opera|safar ...

  4. 【已解决】React中配置Sass引入.scss文件无效

    React中配置Sass引入.scss文件无效 在react中使用sass时,引入.scss文件失效 尝试很多方法没法解决,最终找到解决方法,希望能帮助正在坑里挣扎的筒子~ 在node_modules ...

  5. Django 基于session认证 小作业

    基于session认证  相亲小作业 用户登录 如果男用户登录,显示女生列表 如果女用户登录,显示男生列表 """s4day74 URL Configuration Th ...

  6. kafka_2.12-1.1.0 生产与消费java实现示例

    环境准备: 1)需要在maven工程中引入依赖: <!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka --> &l ...

  7. 卷积神经网络的一些经典网络(Lenet,AlexNet,VGG16,ResNet)

    LeNet – 5网络 网络结构为: 输入图像是:32x32x1的灰度图像 卷积核:5x5,stride=1 得到Conv1:28x28x6 池化层:2x2,stride=2 (池化之后再经过激活函数 ...

  8. Maven 私服的简单使用

    所有的 Java 开发者应该是没有没用过 Maven 的吧.Maven 作为 Java 项目管理工具,它不仅可以用作包管理,还有许多的插件,可以支持整个项目的开发.打包.测试.部署等一系列行为.而包管 ...

  9. JavaScript 递归

    递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.通常涉及 函数调用自身. 能够像下面这样直接调用自身的方法或函数,是递归函数: var recursiveFunction = ...

  10. .NET CORE 2.0之 httpcontext

    HttpContext  在之前的.NET framework 是一个非常常用且强大的类,在.NET CORE2.0中要像以前用是不太方便的了, 要是用sesson 首先需要在startup 的Con ...