Microsoft Corporation
目标
本模块用于:
• | 将加密数据库连接字符串存储在注册表中。 |
• | 从注册表中读取加密数据库连接字符串并将其解密。 |
适用于:
本模块适用于下列产品和技术:
• | Microsoft® Windows® XP 或 Windows 2000 Server(带 Service Pack 3)以及更高版本的操作系统 |
• | Microsoft .NET Framework 版本 1.0(带 Service Pack 2)以及更高版本 |
• | Microsoft Visual C#® .NET 开发工具 |
本模块的使用方法
要最大程度的利用本模块:
• | 必须有使用 Visual C# .NET 编程的经验。 |
• | 必须有使用 Microsoft Visual Studio® .NET 开发环境的经验。 |
• | 必须有使用 ASP.NET 开发 Web 应用程序的经验。 |
• | 创建“How To Create an Encryption Library”中描述的通用加密库。此库提供了本模块中用来加密和解密数据库连接字符串的功能。 |
• | 阅读“Data Access Security”模块中的“Storing Database Connection Strings Securely”一节。此节提供了安全地存储数据库连接字符串所用的各种技术的有关信息。 |
本页内容
摘要 | |
预备知识 | |
将加密数据存储在注册表中 | |
创建一个 ASP.NET Web 应用程序 | |
其他资源 |
摘要
对于编写需要访问数据库的应用程序的任何开发人员而言,他们都面临着应将数据库连接字符串安全地存储在何处这样一个共同的问题。注册表代表一个可能的存储位置。然而,尽管单个注册表项可以用 Microsoft Windows 访问控制列表 (ACL) 来保证安全,但为了实现更好的安全性,应该在对连接字符串进行加密后再存储它们。
本模块描述了如何将加密数据库连接字符串存储在注册表中,以及如何将其从 ASP.NET Web 应用程序中检索出来。它使用了“How to Create an Encryption Library”中创建的通用加密库。
预备知识
在开始使用本模块之前,应了解以下内容:
• | 连接字符串以及用于加密的初始化向量和密钥,在注册表中将作为已命名值存储在下列注册表项下。 HKEY_LOCAL_MACHINE/Software/TestApplication |
• | 为了对连接字符串进行解密,必须存储初始化向量和密钥。 |
将加密数据存储在注册表中
此过程将创建一个用于加密示例数据库字符串并将其存储在注册表中的 Windows 应用程序。
要将加密数据存储在注册表中,请执行下列操作:
1. | 启动 Visual Studio .NET 并创建一个新的名为 EncryptionTestApp 的 Visual C# Windows 项目。 |
2. | 向 Encryption.dll 程序集添加一个程序集引用。 要创建此程序集,必须执行“How To Create an Encryption Library”中所描述的步骤。 |
3. | 将下列 using 语句添加到 Form1.cs 顶部的现有 using 语句下。 using Encryption; using System.Text; using Microsoft.Win32; |
4. | 将表 1 中的控件添加到 Form1,并如图 1 所示安排它们。 |
表 1:EncryptionTestApp 控件 | ||
控件 | 文本 | ID |
Label | Connection String: | |
TextBox | txtConnectionString | |
Label | Key: | |
TextBox | txtKey | |
Label | Initialization Vector: | |
TextBox | txtInitializationVector | |
Label | Encrypted String | |
TextBox | txtEncryptedString | |
Label | Decrypted String | |
TextBox | txtDecryptedString | |
Button | Encrypt | btnEncrypt |
Button | Decrypt | btnDecrypt |
Button | Write Registry Data | btnWriteRegistryData |
图 1. Encryption Test Harness 对话框
1. | 将 txtConnectionString 的 Text 属性设置为 "Server=local; database=pubs; uid=Bob; pwd=Password" |
2. | 将 txtKey 的 Text 属性设置为 "0123456789012345" 密钥长度是 16 字节以符合 Triple DES 加密算法的要求。 |
3. | 将 Form1 的 Text 属性设置为 "Encryption Test Harness" |
4. | 双击 Encrypt 按钮来创建一个按钮单击事件处理程序,然后将下列代码添加到事件处理程序。 try { // Create the encryptor object, specifying 3DES as the // encryption algorithm Encryptor enc = new Encryptor(EncryptionAlgorithm.TripleDes); // Get the connection string as a byte array byte[] plainText = Encoding.ASCII.GetBytes(txtConnectionString.Text); byte[] key = Encoding.ASCII.GetBytes(txtKey.Text); // Perform the encryption byte[] cipherText = enc.Encrypt(plainText, key); // Store the intialization vector, as this will be required // for decryption txtInitializationVector.Text = Encoding.ASCII.GetString(enc.IV); // Display the encrypted string txtEncryptedString.Text = Convert.ToBase64String(cipherText); } catch(Exception ex) { MessageBox.Show("Exception encrypting: " + ex.Message, "Encryption Test Harness"); } |
5. | 返回到 Designer 模式中的 Form1,并双击 Decrypt 按钮来创建一个按钮单击事件处理程序。 |
6. | 将下列代码添加到 Decrypt 按钮事件处理程序中: try { // Set up the Decryptor object Decryptor dec = new Decryptor(EncryptionAlgorithm.TripleDes); // Set the Initialization Vector dec.IV = Encoding.ASCII.GetBytes(txtInitializationVector.Text); byte[] key = Encoding.ASCII.GetBytes(txtKey.Text); // Perform the decryption byte[] plainText = dec.Decrypt(Convert.FromBase64String( txtEncryptedString.Text), key); // Display the decrypted string. txtDecryptedString.Text = Encoding.ASCII.GetString(plainText); } catch(Exception ex) { MessageBox.Show("Exception decrypting. " + ex.Message, "Encryption Test Harness"); } |
7. | 在 Designer 模式中返回到 Form1,并双击 Write Registry Data 按钮来创建一个按钮单击事件处理程序。 |
8. | 将下列代码添加到事件处理程序。 // Create registry key and named values RegistryKey rk = Registry.LocalMachine.OpenSubKey("Software",true); rk = rk.CreateSubKey("TestApplication"); // Write encrypted string, initialization vector and key to the registry rk.SetValue("connectionString",txtEncryptedString.Text); rk.SetValue("initVector",Convert.ToBase64String( Encoding.ASCII.GetBytes(txtInitializationVector.Text))); rk.SetValue("key",Convert.ToBase64String(Encoding.ASCII.GetBytes( txtKey.Text))); MessageBox.Show("The data has been successfully written to the registry"); |
9. | 运行此应用程序,然后单击 Encrypt。 加密连接字符串即显示在 EncryptedString 字段中。 |
10. | 单击 Decrypt。 原始字符串显示在 DecryptedString 字段中。 |
11. | 单击 WriteRegistryData。 |
12. | 在消息框中,单击 OK。 |
13. | 运行 regedit.exe 并查看下列密钥的内容。 HKLM/Software/TestApplication 确认对 connectionString、initVector 和 key 已命名值存在有编码值。 |
14. | 关闭 Regedit 和 Test Harness 应用程序。 |
创建一个 ASP.NET Web 应用程序
此过程开发一个简单的 ASP.NET Web 应用程序,用于从注册表中检索出加密连接字符串并将其解密。
要创建一个 ASP.NET 应用程序,请执行下列操作:
1. | 创建一个名为 EncryptionWebApp 的新的 Visual C# ASP.NET Web 应用程序。 | |||||||||||||||
2. | 向 Encryption.dll 程序集添加一个程序集引用。 要创建此程序集,必须执行“How To Create an Encryption Library”中所描述的步骤。 | |||||||||||||||
3. | 打开 Webform1.aspx.cs 并将下列 using 语句添加到文件顶部的现有 using 语句下。 using Encryption; using System.Text; using Microsoft.Win32; | |||||||||||||||
4. | 将表 2 中所列出的控件添加到 WebForm1.aspx。
|
1. | 双击 Get Connection String 按钮来创建一个按钮单击事件处理程序。 |
2. | 将下列代码添加到事件处理程序。 RegistryKey rk = Registry.LocalMachine.OpenSubKey( @"Software/TestApplication",false); lblEncryptedString.Text = (string)rk.GetValue("connectionString"); string initVector = (string)rk.GetValue("initVector"); string strKey = (string)rk.GetValue("key"); Decryptor dec = new Decryptor(EncryptionAlgorithm.TripleDes ); dec.IV = Convert.FromBase64String(initVector); // Decrypt the string byte[] plainText = dec.Decrypt(Convert.FromBase64String( lblEncryptedString.Text), Convert.FromBase64String(strKey)); lblDecryptedString.Text = Encoding.ASCII.GetString(plainText); |
3. | 在 Build 菜单上,单击 BuildSolution。 |
4. | 右键单击解决方案资源管理器中的 Webform1.aspx,然后单击 View in Browser。 |
5. | 单击 Get Connection String。 已加密和解密的连接字符串在 Web 窗体中显示出来。 |
其他资源
有关详细信息,请参阅“How To Create an Encryption Library”。