看好你的数据库连接字符串!
一般情况下,大多数人习惯于将数据库连接写在web.config上里面,理论上讲,将明文存放在该文件里面是安全的,因为web.config文件是不允许被客户端下载,但一旦该文件泄漏出去,哪怕是很短的时间,数据库都将承受巨大的危害,可能花上N年才充实起来的信息在很短时间里毁于一旦。这是任何程序绝对不应该出现的问题。有人用简单的对称加密来将数据库连接字符串的密文存放,但密钥一旦丢失,加密与否,形同虚设,那么如何保证连接字符串的安全性呢。下面这个类就完成这个功能,该类调用系统API,在不同的系统中对相同的连接串会生成不同的密文,即使非法获得该串,不能获得在服务器上的管理员权限,仍然没有能力知道数据库的真正所在。有人说,那服务器管理员权限也被盗用了呢?那盗用者还需要经过一系列复杂的跟踪和总结,来获得系统标识变量。这无疑又是一个难度,等到他真正破解了解该系统的时候,也许你早就在此之前,改正了服务器的配置和密码,还害得人家白忙活了一趟。够阴的!
呵呵
代码如下:
呵呵
代码如下:
1
using System;
2
using System.Text;
3
using System.Runtime.InteropServices;
4
5
namespace 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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

作者:jillzhang
出处:http://jillzhang.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://jillzhang.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!