如何生成唯一的公共及通过RSA私钥 [英] How to Generate Unique Public and Private Key via RSA
问题描述
我建立一个定制的购物车,其中CC编号和实验日期将被存储在一个数据库中,直到处理(然后删除)。我需要这个数据加密(显然)。
我想使用的RSACryptoServiceProvider类。
下面是我的code创建我的钥匙。
公共静态无效AssignNewKey(){
const int的PROVIDER_RSA_FULL = 1;
常量字符串CONTAINER_NAME =KEYCONTAINER;
CspParameters cspParams;
cspParams =新CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName =微软强加密提供程序;
RSA =新的RSACryptoServiceProvider(cspParams); 字符串publicPrivateKeyXML = rsa.ToXmlString(真);
字符串publicOnlyKeyXML = rsa.ToXmlString(假);
//做的东西的钥匙......
}
现在的计划是私钥XML存储连接到管理者钥匙链USB驱动器上。
当一个经理离开公司,我希望能够产生新的公钥和私钥(和重新加密用新的公钥当前存储CC号码)。
我的问题是,这个code生成的密钥都是一样的。我怎么会每次都生成一个唯一一套钥匙?
更新。我的测试code低于:
的注:这里的privatekey参数是原来的私有密钥。为了要修改的键我需要验证私钥是有效的。的
在Default.aspx.cs
公共无效DownloadNewPrivateKey_Click(对象发件人,EventArgs的发送)
{
StreamReader的读者=新的StreamReader(fileUpload.FileContent);
字符串privateKey = reader.ReadToEnd();
Response.Clear();
Response.ContentType =文/ XML;
到Response.End();
的Response.Write(ChangeKeysAndReturnNewPrivateKey(privateKey));
}
在Crytpography.cs:
公共静态privateKey;
公共静态公钥;
公共静态的RSACryptoServiceProvider RSA;公共静态字符串ChangeKeysAndReturnNewPrivateKey(字符串_privatekey)
{ 字符串TESTDATA =TESTDATA;
字符串testSalt =盐;
//加密使用已有的公开密钥的测试数据...
字符串encryptedTestData = EncryptData(TESTDATA,testSalt);
尝试
{
//尝试解密使用由用户提供的_privatekey测试数据...
字符串decryptTestData = DecryptData(encryptedTestData,_privatekey,testSalt);
//如果数据被成功解密分配新的密钥...
如果(decryptTestData == TESTDATA)
{
AssignNewKey();
//AssignNewKey()应该privateKey设置为新创建的私有密钥...
返回privateKey;
}
其他
{
返回的String.Empty;
}
}
赶上(异常前)
{
返回的String.Empty;
}
}
公共静态无效AssignParameter(){
const int的PROVIDER_RSA_FULL = 1;
常量字符串CONTAINER_NAME =KEYCONTAINER;
CspParameters cspParams;
cspParams =新CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName =微软强加密提供程序;
RSA =新的RSACryptoServiceProvider(cspParams);
}
公共静态无效AssignNewKey()
{
AssignParameter(); 使用(SqlConnection的的myconn =新的SqlConnection(Utilities.ConnectionString))
{
的SqlCommand myCmd = myConn.CreateCommand(); 字符串publicPrivateKeyXML = rsa.ToXmlString(真);
privateKey = publicPrivateKeyXML; //设置公共变量privateKey新的私钥。 字符串publicOnlyKeyXML = rsa.ToXmlString(假);
公钥= publicOnlyKeyXML; //设置公共变量公钥到新的公共密钥。 myCmd.CommandText =更新设置SET公钥= @PublicKey;
myCmd.Parameters.AddWithValue(@公钥,publicOnlyKeyXML);
myConn.Open(); myComm.ExecuteScalar();
}
}
公共静态字符串EncryptData(字符串data2Encrypt,字符串盐)
{
AssignParameter(); 使用(SqlConnection的的myconn =新的SqlConnection(Utilities.ConnectionString))
{
的SqlCommand myCmd = myConn.CreateCommand(); myCmd.CommandText =SELECT TOP 1公钥FROM设置; myConn.Open(); 使用(SDR SqlDataReader的= myCmd.ExecuteReader())
{
如果(sdr.HasRows)
{
DataTable的DT =新的DataTable();
dt.Load(SDR);
rsa.FromXmlString(dt.Rows [0] [公钥]的ToString());
}
}
} //读取明文进行加密以密文
字节[] = plainbytes System.Text.Encoding.UTF8.GetBytes(data2Encrypt +盐);
字节[] = cipherbytes rsa.Encrypt(plainbytes,FALSE);
返回Convert.ToBase64String(cipherbytes);
}
公共静态字符串DecryptData(字符串data2Decrypt,串privatekey,字符串盐)
{
AssignParameter(); 字节[] getPassword来= Convert.FromBase64String(data2Decrypt); 字符串publicPrivateKeyXML = privatekey;
rsa.FromXmlString(publicPrivateKeyXML); //读取密文,解密它明文
字节[] =平原rsa.Decrypt(getPassword来,假的);
字符串dataAndSalt = System.Text.Encoding.UTF8.GetString(平原)
返回dataAndSalt.Substring(0,dataAndSalt.Length - salt.Length);
}
我落得这样做是创建基于注销当前日期时间的新KEYCONTAINER名(DateTime.Now.Ticks.ToString()),每当我需要创建一个新的密钥,并保存在容器的名称和公开密钥的数据库。此外,每当我创建一个新的关键我会做到以下几点:
公共静态字符串ConvertToNewKey(字符串oldPrivateKey)
{ //从数据库中获取当前容器名称... rsa.PersistKeyInCsp = FALSE;
rsa.Clear();
RSA = NULL; 字符串privateKey = AssignNewKey(真); //创建新的公钥和容器名称,并将其写入到数据库中... //重新加密现有数据,以使用新的密钥并写入数据库... 返回privateKey;
}
公共静态字符串AssignNewKey(布尔ReturnPrivateKey){
字符串容器名称= DateTime.Now.Ticks.ToString();
//创建新的关键...
//保存容器名称和公钥数据库...
//返回私钥XML。
}
在创建新的密钥。
I am building a custom shopping cart where CC numbers and Exp date will be stored in a database until processing (then deleted). I need to encrypt this data (obviously).
I want to use the RSACryptoServiceProvider class.
Here is my code to create my keys.
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...
}
Now the plan is to store the private key xml on a USB drive attached to the managers key chain.
Whenever a manager leaves the company I want to be able to generate new public and private keys (and re-encrypt all currently stored CC numbers with the new public key).
My problem is that the keys generated by this code are always the same. How would I generate a unique set of keys every time?
UPDATE. My test code is below.:
note: the "privatekey" parameter here is the original private key. In order for the keys to be changed I need to verify that the private key is valid.
In 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));
}
In 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);
}
What I ended up doing is create a new KeyContainer name based off of the current DateTime (DateTime.Now.Ticks.ToString()) whenever I need to create a new key and save the container name and public key to the database. Also, whenever I create a new key I would do the following:
public static string ConvertToNewKey(string oldPrivateKey)
{
// get the current container name from the database...
rsa.PersistKeyInCsp = false;
rsa.Clear();
rsa = null;
string privateKey = AssignNewKey(true); // create the new public key and container name and write them to the database...
// re-encrypt existing data to use the new keys and write to database...
return privateKey;
}
public static string AssignNewKey(bool ReturnPrivateKey){
string containerName = DateTime.Now.Ticks.ToString();
// create the new key...
// saves container name and public key to database...
// and returns Private Key XML.
}
before creating the new key.
这篇关于如何生成唯一的公共及通过RSA私钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!