Connection对象连接加密2
一般情况下,大多数人习惯于将数据库连接写在web.config上里面,理论上讲,将明文存放在该文件里面是安全的,因为web.config文件是不允许被客户端下载,但一旦该文件泄漏出去,哪怕是很短的时间,数据库都将承受巨大的危害,可能花上N年才充实起来的信息在很短时间里毁于一旦。这是任何程序绝对不应该出现的问题。有人用简单的对称加密来将数据库连接字符串的密文存放,但密钥一旦丢失,加密与否,形同虚设,那么如何保证连接字符串的安全性呢。下面这个类就完成这个功能,该类调用系统API,在不同的系统中对相同的连接串会生成不同的密文,即使非法获得该串,不能获得在服务器上的管理员权限,仍然没有能力知道数据库的真正所在。有人说,那服务器管理员权限也被盗用了呢?那盗用者还需要经过一系列复杂的跟踪和总结,来获得系统标识变量。这无疑又是一个难度,等到他真正破解了解该系统的时候,也许你早就在此之前,改正了服务器的配置和密码,还害得人家白忙活了一趟。够阴的!
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace JillZhang.Security
{
public enum Store
{
USE_NACHINE_STORE=1,USE_USER_STORE
};
public class DataProtector
{
[DllImport("Crypt32.dll",SetLastError=true,CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool CryptProtectData
(
ref DATA_BLOB pDataIn,
String szDataDecr,
ref DATA_BLOB pOptionEntropy,
IntPtr pvReserved,
ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct,
int dwFlags,
ref DATA_BLOB pDataOut
);
[DllImport("Crypt32.dll",SetLastError=true,CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool CryptUnprotectData
(
ref DATA_BLOB pDataIn,
String szDataDecr,
ref DATA_BLOB pOptionEntropy,
IntPtr pvReserved,
ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct,
int dwFlags,
ref DATA_BLOB pDataOut
);
[DllImport("kernel32.dll",CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private unsafe static extern int FormatMessage
(
int dwFlags,
ref IntPtr lpSource,
int dwMessageId,
int dwLanguageId,
ref String lpBuffer,
int nSize,
IntPtr *Arguments
);
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
internal struct DATA_BLOB
{
public int cbData;
public IntPtr pbData;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
internal struct CRYPTPROTECT_PROMPTSTRUCT
{
public int cbSize;
public int dwPromptFlags;
public IntPtr hwndApp;
public String szPrompt;
}
static private IntPtr NullPtr=((IntPtr)((int)(0)));
private const int CRYPTPROTECT_UI_FORBIDDEN=0x1;
private const int CRYPTPROTECT_LOCAL_MACHINE=0x4;
private Store store;
public DataProtector(Store tempStore)
{
store=tempStore;
}
public byte[] Encrypt(byte[] plainText,byte[] optionalEntropy)
{
bool reVal=false;
DATA_BLOB plainTextBlob = new DATA_BLOB();
DATA_BLOB cipherTextBlob=new DATA_BLOB();
DATA_BLOB entropyBlob = new DATA_BLOB();
CRYPTPROTECT_PROMPTSTRUCT prompt=new CRYPTPROTECT_PROMPTSTRUCT();
InitPromptstruct(ref prompt);
int dwFlags;
try
{
try
{
int byteSize=plainText.Length;
plainTextBlob.pbData=Marshal.AllocHGlobal(byteSize);
if(IntPtr.Zero==plainTextBlob.pbData)
{
throw new Exception("Unable to allocate plaintext buffer:");
}
plainTextBlob.cbData=byteSize;
Marshal.Copy(plainText,0,plainTextBlob.pbData,byteSize);
}
catch(Exception ex)
{
throw new Exception("Exception marshalling data.:"+ex.Message);
}
if(Store.USE_NACHINE_STORE==store)
{
//计算机存储区
dwFlags=CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN;
if(null==optionalEntropy)
{
optionalEntropy=new byte[0];
}
try
{
int byteSize=optionalEntropy.Length;
entropyBlob.pbData=Marshal.AllocHGlobal(optionalEntropy.Length);
if(IntPtr.Zero==entropyBlob.pbData)
{
throw new Exception("Unable to allocate entropy data buffer.");
}
Marshal.Copy(optionalEntropy,0,entropyBlob.pbData,byteSize);
entropyBlob.cbData=byteSize;
}
catch(Exception ex)
{
throw new Exception("Exception entropy marshalling data."+ex.Message);
}
}
else
{
dwFlags=CRYPTPROTECT_UI_FORBIDDEN;
}
reVal=CryptProtectData(ref plainTextBlob,"",ref entropyBlob,IntPtr.Zero,ref prompt,dwFlags,ref cipherTextBlob);
if(false == reVal)
{
throw new Exception("Encryption failed."+GetErrorMessage(Marshal.GetLastWin32Error()));
}
}
catch(Exception ex)
{
throw new Exception("Exception encrypting:"+ex.Message);
}
byte[] cipherText = new byte[cipherTextBlob.cbData];
Marshal.Copy(cipherTextBlob.pbData,cipherText,0,cipherTextBlob.cbData);
return cipherText;
}
public byte[] Decrypt(byte[] ciperText,byte[] optionalEntropy)
{
bool reVal=false;
DATA_BLOB plainTextBlob=new DATA_BLOB();
DATA_BLOB cipherBlob=new DATA_BLOB();
CRYPTPROTECT_PROMPTSTRUCT prompt=new CRYPTPROTECT_PROMPTSTRUCT();
InitPromptstruct(ref prompt);
try
{
try
{
int cipherTextSize=ciperText.Length;
cipherBlob.pbData=Marshal.AllocHGlobal(cipherTextSize);
if(IntPtr.Zero==cipherBlob.pbData)
{
throw new Exception("unable to allocate cipherText buffer.");
}
cipherBlob.cbData=cipherTextSize;
Marshal.Copy(ciperText,0,cipherBlob.pbData,cipherBlob.cbData);
}
catch(Exception ex)
{
throw new Exception("Exception marshalling data."+ex.Message);
}
DATA_BLOB entropyBlob=new DATA_BLOB();
int dwFlags;
if(Store.USE_NACHINE_STORE==store)
{
dwFlags=CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN;
if(null==optionalEntropy)
{
optionalEntropy=new byte[0];
}
try
{
int byteSize=optionalEntropy.Length;
entropyBlob.pbData=Marshal.AllocHGlobal(byteSize);
if(IntPtr.Zero==entropyBlob.pbData)
{
throw new Exception("Unable to allocate entropy buffer.");
}
entropyBlob.cbData=byteSize;
Marshal.Copy(optionalEntropy,0,entropyBlob.pbData,byteSize);
}
catch(Exception ex)
{
throw new Exception("Exception entropy marshalling data."+ex.Message);
}
}
else
{
dwFlags=CRYPTPROTECT_UI_FORBIDDEN;
}
reVal=CryptUnprotectData(ref cipherBlob,null,ref entropyBlob,IntPtr.Zero,ref prompt,dwFlags,ref plainTextBlob);
if(false==reVal)
{
throw new Exception("Decryption failed."+GetErrorMessage(Marshal.GetLastWin32Error()));
}
if(IntPtr.Zero!=cipherBlob.pbData)
{
Marshal.FreeHGlobal(cipherBlob.pbData);
}
if(IntPtr.Zero!=entropyBlob.pbData)
{
Marshal.FreeHGlobal(entropyBlob.pbData);
}
}
catch(Exception ex)
{
throw new Exception("Exception decrypting."+ex.Message);
}
byte[] plainText=new byte[plainTextBlob.cbData];
Marshal.Copy(plainTextBlob.pbData,plainText,0,plainTextBlob.cbData);
return plainText;
}
private void InitPromptstruct(ref CRYPTPROTECT_PROMPTSTRUCT ps)
{
ps.cbSize=Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT));
ps.dwPromptFlags=0;
ps.hwndApp=NullPtr;
ps.szPrompt=null;
}
private unsafe static String GetErrorMessage(int errorCode)
{
int FORMAT_MESSAGE_ALLOCATE_BUFFER=0x00000100;
int FORMAT_MESSAGE_IGNORE_INSERTS=0x00000200;
int FORMAT_MESSAGE_FROM_SYSTEM=0x00001000;
int messageSize=255;
String lpMsgBuf="";
int dwFlags=FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS;
IntPtr ptrlpSource=new IntPtr();
IntPtr ptrArgument=new IntPtr();
int retVal=FormatMessage(dwFlags,ref ptrlpSource,errorCode,0,ref lpMsgBuf,messageSize,&ptrArgument);
if(0==retVal)
{
throw new Exception("Failed to format message for error code"+errorCode+".");
}
return lpMsgBuf;
}
}
}
Connection对象连接加密2的更多相关文章
- connection String加密
aspnet_regiis -pe "connectionStrings" -app "/HG" -prov "ChrisProvider" ...
- Connection 连接字符串释义
本文将详细介绍如何使用Connection对象连接数据库.对于不同的.NET数据提供者,ADO.NET采用不同的Connection对象连接数据库.这些Connection对象为我们屏蔽了具体的实现细 ...
- C#与数据库访问技术总结(三)之 Connection对象的常用方法
说明:前面(一)(二)总结了数据库连接的概念以及连接数据库的字符串中的各个参数的含义.这篇随笔介绍connection对象的常用方法. Connection对象的常用方法 Connection类型的对 ...
- (1)C#连接数据库:Connection对象
连接数据库:Connection对象 1.Connection对象概述 Connection对象是一个连接对象,主要功能是建立与物理数据库的连接.其主要包括4种访问数据库的对象类,也可称为数据提供 ...
- C# 连接SQL Server数据库的几种方式--server+data source等方式
如何使用Connection对象连接数据库? 对于不同的.NET数据提供者,ADO.NET采用不同的Connection对象连接数据库.这些Connection对象为我们屏蔽了具体的实现细节,并提供了 ...
- SQL Server 2008连接字符串写法大全
一..NET Framework Data Provider for SQL Server 类型:.NET Framework类库使用:System.Data.SqlClient.SqlConnect ...
- ODBC与ADO 连SQL Server 2005
ADO是microsoft数据库应用程序开发的连连接口,是建立在OLE DB之上的高层 ADO使用方法步骤: 1.初始化COM库,引入ADO库定义 2.用connection对象连接数据库 3.利用连 ...
- ADO.NET操作数据库(一)
---恢复内容开始--- [1]ADO.Net简介2015-12-07-20:16:05 ADO.Net提供对Microsoft SQL Server数据源以及通过OLE DB和XML公开的数据源的一 ...
- Tabular Model下的ADOMD.NET
ADOMD.NET是一套对象架构体系,它包含需要向SSAS数据库做访问的一切支持的对象和方法.很多微软官方以及第三方的SSAS客户端应用都是通过这个对象来操作数据. 多维模式的ADOMD.NET在我以 ...
随机推荐
- lrj计算几何模板
整理了一下大白书上的计算几何模板. #include <cstdio> #include <algorithm> #include <cmath> #include ...
- UVa 12563 Jin Ge Jin Qu hao【01背包】
题意:给出t秒时间,n首歌分别的时间a[i],还给出一首长度为678的必须唱的劲歌金曲,问最多能够唱多少首歌(只要最后时间还剩余一秒,都可以将劲歌金曲唱完) 用dp[i]代表花费i时间时唱的歌的最大数 ...
- 转:MVC 下导航超链接本页面高亮的一种解决方案
前言 导航高亮一直是一个让大家头疼的问题. 纯 Javascript 的话可以判断当前页面的地址和链接地址是否有关系. 这样的弊端就是自由度太低,MVC 下会出一定的问题 (MVC 下有默认的 Con ...
- Android Studio 我常用快捷键
0. Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类 1. 重载方法 Ctrl+O 2.Ctrl+shift+Enter:自动匹配相对应的语法结构,比如if,do-while,t ...
- 用ioctl获取无线网络信息 /usr//include/linux/wireless.h
1.UNIX Network Programming环境搭建 Unix NetWork Programming――环境搭建(解决unp.h等源码编译问题) http://blog.csdn.net/a ...
- python 去掉\n\t多余空格
>>> import re >>> sss = "SELECT a.id,\n a.customer_id as user_id,\n ...
- Oracle :一次数据库连接,返回多个结果集
1. 一次数据库连接,返回多个结果集 1.1 建立包规范 create or replace package QX_GDJTJ is -- Author : xxx -- Created : 2012 ...
- Maximum Random Walk(概率dp)
题意: 走n步,给出每步向左走概率l,向右走概率r,留在原地的概率 1-l-r,求能达到的最远右边距离的期望. 分析: 开始按期望逆求的方式分析,但让求的就是右边界没法退,懵了一会,既然逆着不能求,就 ...
- IOCP模型
IOCP http://blog.csdn.net/zhongguoren666/article/details/7386592 Winsock IO模型之IOCP模型 http://blog.csd ...
- Shell获取Aix/linux/unix机器上db2和os的信息并上传到指定服务器
(之前写过一篇类似的文章,当时传输文件用的是ftp,因为项目觉得ftp不够安全所以这次换成了scp,同时对脚本的一些地方也做了一些调整) 其实做这个东西还是因为项目的需求,需要获取某些机器(目前主要是 ...