一般情况下,大多数人习惯于将数据库连接写在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的更多相关文章

  1. connection String加密

    aspnet_regiis -pe "connectionStrings" -app "/HG" -prov "ChrisProvider" ...

  2. Connection 连接字符串释义

    本文将详细介绍如何使用Connection对象连接数据库.对于不同的.NET数据提供者,ADO.NET采用不同的Connection对象连接数据库.这些Connection对象为我们屏蔽了具体的实现细 ...

  3. C#与数据库访问技术总结(三)之 Connection对象的常用方法

    说明:前面(一)(二)总结了数据库连接的概念以及连接数据库的字符串中的各个参数的含义.这篇随笔介绍connection对象的常用方法. Connection对象的常用方法 Connection类型的对 ...

  4. (1)C#连接数据库:Connection对象

    连接数据库:Connection对象 1.Connection对象概述   Connection对象是一个连接对象,主要功能是建立与物理数据库的连接.其主要包括4种访问数据库的对象类,也可称为数据提供 ...

  5. C# 连接SQL Server数据库的几种方式--server+data source等方式

    如何使用Connection对象连接数据库? 对于不同的.NET数据提供者,ADO.NET采用不同的Connection对象连接数据库.这些Connection对象为我们屏蔽了具体的实现细节,并提供了 ...

  6. SQL Server 2008连接字符串写法大全

    一..NET Framework Data Provider for SQL Server 类型:.NET Framework类库使用:System.Data.SqlClient.SqlConnect ...

  7. ODBC与ADO 连SQL Server 2005

    ADO是microsoft数据库应用程序开发的连连接口,是建立在OLE DB之上的高层 ADO使用方法步骤: 1.初始化COM库,引入ADO库定义 2.用connection对象连接数据库 3.利用连 ...

  8. ADO.NET操作数据库(一)

    ---恢复内容开始--- [1]ADO.Net简介2015-12-07-20:16:05 ADO.Net提供对Microsoft SQL Server数据源以及通过OLE DB和XML公开的数据源的一 ...

  9. Tabular Model下的ADOMD.NET

    ADOMD.NET是一套对象架构体系,它包含需要向SSAS数据库做访问的一切支持的对象和方法.很多微软官方以及第三方的SSAS客户端应用都是通过这个对象来操作数据. 多维模式的ADOMD.NET在我以 ...

随机推荐

  1. UVa 437 (变形的LIS) The Tower of Babylon

    题意: 有n种类型的长方体,每种长方体的个数都有无限个.当一个长方体的长和宽分别严格小于另一个长方体的长和宽的时候,才可以把这个放到第二个上面去.输出这n种长方体能组成的最大长度. 分析: 虽说每种都 ...

  2. UVa 12169 (枚举+扩展欧几里得) Disgruntled Judge

    题意: 给出四个数T, a, b, x1,按公式生成序列 xi = (a*xi-1 + b) % 10001 (2 ≤ i ≤ 2T) 给出T和奇数项xi,输出偶数项xi 分析: 最简单的办法就是直接 ...

  3. OpenSSL再爆多处高危漏洞

    OpenSSL团队于北京时间6月5号晚8点左右发布了5个安全补丁,这次的更新涉及多处高危漏洞,连接:http://www.openssl.org/news/ 受影响的版本包括: OpenSSL 1.0 ...

  4. oracle 11g rac 无法自动启动

    如果以上的操作依然不能使数据库资源自动启动,那么参考下面这篇文章修改资源AUTO_START属性. 查看资源状态: crsctl status resource 资源       -p     crs ...

  5. 纯css3写的仿真图书翻页效果

    对css3研究越深入,越觉得惊艳.css3说不上是万能的,但是它能实现的效果也超出了我的想象.它的高效率和动画效果的流畅性很多情况下能替代js的作用.个人习惯css3能实现的效果就不会用js,虽然在国 ...

  6. USACO1.4.1 Packing Rectangles

    //毕竟我不是dd牛,USACO的题解也不可能一句话带过的…… 题目链接:http://cerberus.delos.com:790/usacoprob2?a=pWvHFwGsTb2&S=pa ...

  7. LeetCode: pow

    Title: https://leetcode.com/problems/powx-n/ 思路:二分.使用递归或者非递归.非递归有点难理解.pow(0,0)=1 递归的方法是将n为负数的用除法解决.有 ...

  8. <八>面向对象分析之UML核心元素之分析类

    一:基本概念        ---->在那大数项目中,分析类是被忽视的一种非常有用的元素.        ---->分析类用于获取系统中主要的“职责簇”,他们代表系统的原型类,是系统必须处 ...

  9. codeforces 679A Bear and Prime 100 交互

    第一次交互题,记录一下吧 #include <cstdio> #include <iostream> #include <ctime> #include <v ...

  10. KindEditor Asp.net

    最近在使用KindEditor,其中遇到三个问题: 1.textarea添加 runat="server" 后整个editor在运行的时候不能显示出来,我没找到原因,于是我就把ru ...