看好你的数据库连接字符串!

一般情况下,大多数人习惯于将数据库连接写在web.config上里面,理论上讲,将明文存放在该文件里面是安全的,因为web.config文件是不允许被客户端下载,但一旦该文件泄漏出去,哪怕是很短的时间,数据库都将承受巨大的危害,可能花上N年才充实起来的信息在很短时间里毁于一旦。这是任何程序绝对不应该出现的问题。有人用简单的对称加密来将数据库连接字符串的密文存放,但密钥一旦丢失,加密与否,形同虚设,那么如何保证连接字符串的安全性呢。下面这个类就完成这个功能,该类调用系统API,在不同的系统中对相同的连接串会生成不同的密文,即使非法获得该串,不能获得在服务器上的管理员权限,仍然没有能力知道数据库的真正所在。有人说,那服务器管理员权限也被盗用了呢?那盗用者还需要经过一系列复杂的跟踪和总结,来获得系统标识变量。这无疑又是一个难度,等到他真正破解了解该系统的时候,也许你早就在此之前,改正了服务器的配置和密码,还害得人家白忙活了一趟。够阴的!
呵呵
代码如下:
  1using System;
  2using System.Text;
  3using System.Runtime.InteropServices;
  4
  5namespace JillZhang.Security
  6{
  7    public enum  Store
  8    {
  9        USE_NACHINE_STORE=1,USE_USER_STORE
 10    }
;
 11    public class DataProtector
 12    {
 13        
 14        [DllImport("Crypt32.dll",SetLastError=true,CharSet=System.Runtime.InteropServices.CharSet.Auto)]
 15        private static extern bool CryptProtectData
 16            (
 17            ref DATA_BLOB pDataIn,
 18            String szDataDecr,
 19            ref DATA_BLOB pOptionEntropy,
 20            IntPtr pvReserved,
 21            ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct,
 22            int dwFlags,
 23            ref DATA_BLOB pDataOut
 24            );
 25
 26        [DllImport("Crypt32.dll",SetLastError=true,CharSet=System.Runtime.InteropServices.CharSet.Auto)]
 27        private static extern bool CryptUnprotectData
 28            (
 29            ref DATA_BLOB pDataIn,
 30            String szDataDecr,
 31            ref DATA_BLOB pOptionEntropy,
 32            IntPtr pvReserved,
 33            ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct,
 34            int dwFlags,
 35            ref DATA_BLOB pDataOut
 36            );
 37
 38        [DllImport("kernel32.dll",CharSet=System.Runtime.InteropServices.CharSet.Auto)]
 39        private unsafe static extern int FormatMessage
 40            (
 41            int dwFlags,
 42            ref IntPtr lpSource,
 43            int dwMessageId,
 44            int dwLanguageId,
 45            ref String lpBuffer,
 46            int nSize,
 47            IntPtr *Arguments
 48            );
 49        [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
 50            internal struct DATA_BLOB
 51        {
 52            public int cbData;
 53            public IntPtr pbData;
 54        }

 55        [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
 56            internal struct CRYPTPROTECT_PROMPTSTRUCT
 57        {
 58            public  int cbSize;
 59            public int dwPromptFlags;
 60            public IntPtr hwndApp;
 61            public String szPrompt;
 62        }

 63        static  private  IntPtr NullPtr=((IntPtr)((int)(0)));
 64        private const int CRYPTPROTECT_UI_FORBIDDEN=0x1;
 65        private const int CRYPTPROTECT_LOCAL_MACHINE=0x4;
 66    
 67        private Store store;
 68        public DataProtector(Store tempStore)
 69        {
 70            store=tempStore;            
 71        }

 72        public byte[] Encrypt(byte[] plainText,byte[] optionalEntropy)
 73        {
 74            bool reVal=false;
 75            DATA_BLOB plainTextBlob = new DATA_BLOB();
 76            DATA_BLOB cipherTextBlob=new DATA_BLOB();
 77            DATA_BLOB entropyBlob = new DATA_BLOB();
 78            CRYPTPROTECT_PROMPTSTRUCT prompt=new CRYPTPROTECT_PROMPTSTRUCT();
 79            InitPromptstruct(ref prompt);
 80            int dwFlags;
 81            try
 82            {
 83                try
 84                {
 85                    int byteSize=plainText.Length;
 86                    plainTextBlob.pbData=Marshal.AllocHGlobal(byteSize);
 87                    if(IntPtr.Zero==plainTextBlob.pbData)
 88                    {
 89                        throw new Exception("Unable to allocate plaintext buffer:");
 90                    }

 91                    plainTextBlob.cbData=byteSize;
 92                    Marshal.Copy(plainText,0,plainTextBlob.pbData,byteSize);  
 93                }

 94                catch(Exception ex)
 95                {
 96                    throw new Exception("Exception marshalling data.:"+ex.Message);
 97                }

 98                if(Store.USE_NACHINE_STORE==store)
 99                {
100                    //计算机存储区
101                    dwFlags=CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN;
102                    if(null==optionalEntropy)
103                    {
104                        optionalEntropy=new byte[0];
105                    }

106                    try
107                    {
108                        int byteSize=optionalEntropy.Length;
109                        entropyBlob.pbData=Marshal.AllocHGlobal(optionalEntropy.Length);
110                        if(IntPtr.Zero==entropyBlob.pbData)
111                        {
112                            throw new Exception("Unable to allocate entropy data buffer.");
113                        }

114                        Marshal.Copy(optionalEntropy,0,entropyBlob.pbData,byteSize);
115                        entropyBlob.cbData=byteSize;
116                    }

117                    catch(Exception ex)
118                    {
119                        throw new Exception("Exception entropy marshalling data."+ex.Message);
120                    }
    
121                }

122                else
123                {
124                    dwFlags=CRYPTPROTECT_UI_FORBIDDEN;
125                }

126                reVal=CryptProtectData(ref plainTextBlob,"",ref entropyBlob,IntPtr.Zero,ref prompt,dwFlags,ref cipherTextBlob);
127                if(false == reVal)
128                {
129                    throw new Exception("Encryption failed."+GetErrorMessage(Marshal.GetLastWin32Error()));
130                }

131            }

132            catch(Exception ex)
133            {
134                throw new Exception("Exception encrypting:"+ex.Message);
135            }

136            byte[] cipherText = new byte[cipherTextBlob.cbData];
137            Marshal.Copy(cipherTextBlob.pbData,cipherText,0,cipherTextBlob.cbData);
138            return cipherText;
139        }

140        public byte[] Decrypt(byte[] ciperText,byte[] optionalEntropy)
141        {
142            bool reVal=false;
143            DATA_BLOB plainTextBlob=new DATA_BLOB();
144            DATA_BLOB cipherBlob=new DATA_BLOB();
145            CRYPTPROTECT_PROMPTSTRUCT prompt=new CRYPTPROTECT_PROMPTSTRUCT();
146            InitPromptstruct(ref prompt);
147            try
148            {
149                try
150                {
151                    int cipherTextSize=ciperText.Length;
152                    cipherBlob.pbData=Marshal.AllocHGlobal(cipherTextSize);
153                    if(IntPtr.Zero==cipherBlob.pbData)
154                    {
155                        throw new Exception("unable to allocate cipherText buffer.");
156                    }

157                    cipherBlob.cbData=cipherTextSize;
158                    Marshal.Copy(ciperText,0,cipherBlob.pbData,cipherBlob.cbData);
159                }

160                catch(Exception ex)
161                {
162                    throw new Exception("Exception marshalling data."+ex.Message);
163                }

164                DATA_BLOB entropyBlob=new DATA_BLOB();
165                int dwFlags;
166                if(Store.USE_NACHINE_STORE==store)
167                {
168                    dwFlags=CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN;
169                    if(null==optionalEntropy)
170                    {
171                        optionalEntropy=new byte[0];
172                    }

173                    try
174                    {
175                        int byteSize=optionalEntropy.Length;
176                        entropyBlob.pbData=Marshal.AllocHGlobal(byteSize);
177                        if(IntPtr.Zero==entropyBlob.pbData)
178                        {
179                            throw new Exception("Unable to allocate entropy buffer.");
180                        }

181                        entropyBlob.cbData=byteSize;
182                        Marshal.Copy(optionalEntropy,0,entropyBlob.pbData,byteSize);
183                    }

184                    catch(Exception ex)
185                    {
186                        throw new Exception("Exception entropy marshalling data."+ex.Message);
187                    }

188                }

189                else
190                {
191                    dwFlags=CRYPTPROTECT_UI_FORBIDDEN;
192                }

193                reVal=CryptUnprotectData(ref cipherBlob,null,ref entropyBlob,IntPtr.Zero,ref prompt,dwFlags,ref plainTextBlob);
194                if(false==reVal)
195                {
196                    throw new Exception("Decryption failed."+GetErrorMessage(Marshal.GetLastWin32Error()));
197                }

198                if(IntPtr.Zero!=cipherBlob.pbData)
199                {
200                    Marshal.FreeHGlobal(cipherBlob.pbData);
201                }

202                if(IntPtr.Zero!=entropyBlob.pbData)
203                {
204                    Marshal.FreeHGlobal(entropyBlob.pbData);
205                }

206                
207            }

208            catch(Exception ex)
209            {
210                throw new Exception("Exception decrypting."+ex.Message);
211            }

212            byte[] plainText=new byte[plainTextBlob.cbData];
213            Marshal.Copy(plainTextBlob.pbData,plainText,0,plainTextBlob.cbData);
214            return plainText;
215        }

216
217        private void InitPromptstruct(ref CRYPTPROTECT_PROMPTSTRUCT ps)
218        {
219            ps.cbSize=Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT));
220            ps.dwPromptFlags=0;
221            ps.hwndApp=NullPtr;
222            ps.szPrompt=null;
223        }

224        private unsafe static String GetErrorMessage(int errorCode)
225        {
226            int FORMAT_MESSAGE_ALLOCATE_BUFFER=0x00000100;
227            int FORMAT_MESSAGE_IGNORE_INSERTS=0x00000200;
228            int FORMAT_MESSAGE_FROM_SYSTEM=0x00001000;
229            int messageSize=255;
230            String lpMsgBuf="";
231            int dwFlags=FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS;
232            IntPtr ptrlpSource=new IntPtr();
233            IntPtr ptrArgument=new IntPtr();
234            int retVal=FormatMessage(dwFlags,ref ptrlpSource,errorCode,0,ref lpMsgBuf,messageSize,&ptrArgument);
235            if(0==retVal)
236            {
237                throw new Exception("Failed to format message for error code"+errorCode+".");
238            }

239            return lpMsgBuf;
240        }

241
242    }

243}

244
posted @ 2006-03-31 19:59  Robin Zhang  阅读(856)  评论(0编辑  收藏  举报