如何生成唯一的公共及通过RSA私钥 [英] How to Generate Unique Public and Private Key via RSA

查看:111
本文介绍了如何生成唯一的公共及通过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 RS​​A;公共静态字符串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(da​​ta2Decrypt);    字符串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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆