我正在构建一个自定义购物车,其中 CC 编号和 Exp 日期将存储在数据库中,直到处理(然后删除)。我需要加密这些数据(显然)。
我想使用 RSACryptoServiceProvider 类。
这是我创建密钥的代码。
public static void AssignNewKey(){
const int PROVIDER_RSA_FULL = 1;
const string CONTAINER_NAME = "KeyContainer";
CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
rsa = new RSACryptoServiceProvider(cspParams);
string publicPrivateKeyXML = rsa.ToXmlString(true);
string publicOnlyKeyXML = rsa.ToXmlString(false);
// do stuff with keys...
}
现在计划将私钥 xml 存储在连接到管理器密钥链的 USB 驱动器上。
每当经理离开公司时,我都希望能够生成新的公钥和私钥(并用新的公钥重新加密所有当前存储的 CC 号码)。
我的问题是这段代码生成的密钥总是相同的。我如何每次生成一组唯一的密钥?
更新。我的测试代码如下:
注意:这里的“privatekey”参数是原始私钥。为了更改密钥,我需要验证私钥是否有效。
在 Default.aspx.cs
public void DownloadNewPrivateKey_Click(object sender, EventArgs e)
{
StreamReader reader = new StreamReader(fileUpload.FileContent);
string privateKey = reader.ReadToEnd();
Response.Clear();
Response.ContentType = "text/xml";
Response.End();
Response.Write(ChangeKeysAndReturnNewPrivateKey(privateKey));
}
在 Crytpography.cs 中:
public static privateKey;
public static publicKey;
public static RSACryptoServiceProvider rsa;
public static string ChangeKeysAndReturnNewPrivateKey(string _privatekey)
{
string testData = "TestData";
string testSalt = "salt";
// encrypt the test data using the exisiting public key...
string encryptedTestData = EncryptData(testData, testSalt);
try
{
// try to decrypt the test data using the _privatekey provided by user...
string decryptTestData = DecryptData(encryptedTestData, _privatekey, testSalt);
// if the data is successfully decrypted assign new keys...
if (decryptTestData == testData)
{
AssignNewKey();
// "AssignNewKey()" should set "privateKey" to the newly created private key...
return privateKey;
}
else
{
return string.Empty;
}
}
catch (Exception ex)
{
return string.Empty;
}
}
public static void AssignParameter(){
const int PROVIDER_RSA_FULL = 1;
const string CONTAINER_NAME = "KeyContainer";
CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
rsa = new RSACryptoServiceProvider(cspParams);
}
public static void AssignNewKey()
{
AssignParameter();
using (SqlConnection myConn = new SqlConnection(Utilities.ConnectionString))
{
SqlCommand myCmd = myConn.CreateCommand();
string publicPrivateKeyXML = rsa.ToXmlString(true);
privateKey = publicPrivateKeyXML; // sets the public variable privateKey to the new private key.
string publicOnlyKeyXML = rsa.ToXmlString(false);
publicKey = publicOnlyKeyXML; // sets the public variable publicKey to the new public key.
myCmd.CommandText = "UPDATE Settings SET PublicKey = @PublicKey";
myCmd.Parameters.AddWithValue("@PublicKey", publicOnlyKeyXML);
myConn.Open();
myComm.ExecuteScalar();
}
}
public static string EncryptData(string data2Encrypt, string salt)
{
AssignParameter();
using (SqlConnection myConn = new SqlConnection(Utilities.ConnectionString))
{
SqlCommand myCmd = myConn.CreateCommand();
myCmd.CommandText = "SELECT TOP 1 PublicKey FROM Settings";
myConn.Open();
using (SqlDataReader sdr = myCmd.ExecuteReader())
{
if (sdr.HasRows)
{
DataTable dt = new DataTable();
dt.Load(sdr);
rsa.FromXmlString(dt.Rows[0]["PublicKey"].ToString());
}
}
}
//read plaintext, encrypt it to ciphertext
byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data2Encrypt + salt);
byte[] cipherbytes = rsa.Encrypt(plainbytes, false);
return Convert.ToBase64String(cipherbytes);
}
public static string DecryptData(string data2Decrypt, string privatekey, string salt)
{
AssignParameter();
byte[] getpassword = Convert.FromBase64String(data2Decrypt);
string publicPrivateKeyXML = privatekey;
rsa.FromXmlString(publicPrivateKeyXML);
//read ciphertext, decrypt it to plaintext
byte[] plain = rsa.Decrypt(getpassword, false);
string dataAndSalt = System.Text.Encoding.UTF8.GetString(plain);
return dataAndSalt.Substring(0, dataAndSalt.Length - salt.Length);
}