我正在为一个非营利组织提供免费咨询,他们想要一个简单的系统来管理具有日程组件等的多个组,并管理孩子的医疗信息。它都在一个excel文件上,但这个问题对护士来说不是很方便。所以我正在构建这个 asp.net 应用程序,当它涉及敏感数据的加密时,我碰壁了。我根据本网站的书籍和建议编写了这个 c# 代码。我做得对吗?
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web.UI.WebControls;
public partial class SymmetricEncryptionWithPassword : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Encrypt_OnClick(object sender, EventArgs e)
{
// Initialize the algorithm from the values on the page.
SymmetricAlgorithm symmetricAlgorithm = new AesManaged();
byte[] generatedKey = null;
byte[] generatedIV = null;
TextBox salt = (TextBox)DetailsView1.FindControl("TextBox2");
TextBox ssn = (TextBox)DetailsView1.FindControl("TextBox1");
salt.Text = Convert.ToBase64String(GenerateSalt());
GetKeyAndIVFromPasswordAndSalt(this.password.Text, Convert.FromBase64String(salt.Text), symmetricAlgorithm, ref generatedKey, ref generatedIV);
symmetricAlgorithm.Key = generatedKey;
symmetricAlgorithm.IV = generatedIV;
ICryptoTransform encryptor = symmetricAlgorithm.CreateEncryptor(symmetricAlgorithm.Key, symmetricAlgorithm.IV);
// Create the streams used for encryption.
MemoryStream memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
byte[] plainTextAsBytes = new UTF8Encoding(false).GetBytes(ssn.Text);
cryptoStream.Write(plainTextAsBytes, 0, plainTextAsBytes.Length);
}
symmetricAlgorithm.Clear();
byte[] encryptedData = memoryStream.ToArray();
ssn.Text = Convert.ToBase64String(encryptedData);
}
protected void Decrypt_OnClick(object sender, EventArgs e)
{
// Initialize the algorithm from the values on the page.
SymmetricAlgorithm symmetricAlgorithm = new AesManaged();
byte[] generatedKey = null;
byte[] generatedIV = null;
TextBox txt = (TextBox)DetailsView1.FindControl("TextBox2");
TextBox txt1 = (TextBox)DetailsView1.FindControl("TextBox1");
GetKeyAndIVFromPasswordAndSalt(this.password.Text, Convert.FromBase64String(txt.Text), symmetricAlgorithm, ref generatedKey, ref generatedIV);
symmetricAlgorithm.Key = generatedKey;
symmetricAlgorithm.IV = generatedIV;
ICryptoTransform decryptor = symmetricAlgorithm.CreateDecryptor(symmetricAlgorithm.Key, symmetricAlgorithm.IV);
// Create the streams used for encryption.
MemoryStream memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write))
{
byte[] encryptedDataAsBytes = Convert.FromBase64String(txt1.Text);
cryptoStream.Write(encryptedDataAsBytes, 0, encryptedDataAsBytes.Length);
}
symmetricAlgorithm.Clear();
byte[] decryptedData = memoryStream.ToArray();
txt1.Text = Encoding.UTF8.GetString(decryptedData);
}
private static byte[] GenerateSalt()
{
const int MinSaltSize = 8;
const int MaxSaltSize = 16;
// Generate a random number to determine the salt size.
Random random = new Random();
int saltSize = random.Next(MinSaltSize, MaxSaltSize);
// Allocate a byte array, to hold the salt.
byte[] saltBytes = new byte[saltSize];
// Initialize the cryptographically secure random number generator.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
// Fill the salt with cryptographically strong byte values.
rng.GetNonZeroBytes(saltBytes);
return saltBytes;
}
private static void GetKeyAndIVFromPasswordAndSalt(string password, byte[] salt, SymmetricAlgorithm symmetricAlgorithm, ref byte[] key, ref byte[] iv)
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt);
key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
iv = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8);
}
}
}
该代码有效,当我输入数据时,它在数据库中加密,并且正确的 Salt 与值一起存储。例如,当我希望它在文本框中解密时,它可以正常工作。
我的想法是:护士在表格中输入数据,她用密码对其进行加密,服务器生成加密的医疗保险号码和盐值,然后发送到 SQL 服务器,医疗保险在看起来像这样的表中加密.
Medicare_ID - int(主键)
Medicar_Number - (varchar(MAX))
Medicare_SALT - (varchar(MAX))
解密密码没有存储在数据库中,我是故意这样做的。
我只是不确定我是否遵循这里的最佳实践,如果物理服务器被盗,我的信息是否可以轻松解密?他们仍然需要密码才能解密数据吗?我们有时需要在紧急情况下对其进行解密。我的解密方法安全吗?另一个问题是我使用 1and1 共享虚拟主机。
我已经设置了一些更多的安全措施,例如将在网站上激活 SSL,以便对信息进行加密并防止掉眼。
我将确保对连接字符串和输入进行清理以防万一,但理论上只有 1-2 名经理或护士会操纵数据。
网站访问受到用户名密码的保护,该用户名密码带有我从 Visual Studio 2010 借来的登录控件。
感谢您抽时间阅读