RSA를 통해 고유 한 공개 및 개인 키를 생성하는 방법
CC 번호와 만료일이 처리 (삭제) 될 때까지 데이터베이스에 저장되는 맞춤형 장바구니를 만들고 있습니다. 이 데이터를 암호화해야합니다 (분명히).
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...
}
이제 계획은 관리자 키 체인에 연결된 USB 드라이브에 개인 키 xml을 저장하는 것입니다.
관리자가 회사를 떠날 때마다 새 공개 및 개인 키를 생성하고 새 공개 키로 현재 저장된 모든 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);
}
다음과 같은 코드를 사용할 때 :
using (var rsa = new RSACryptoServiceProvider(1024))
{
// Do something with the key...
// Encrypt, export, etc.
}
.NET (실제로 Windows)은 영구 키 컨테이너에 키를 영원히 저장합니다 . 컨테이너는 .NET에서 무작위로 생성됩니다.
이것은 다음을 의미합니다.
데이터 보호, 사용자 지정 X.509 인증서 생성 등의 목적으로 생성 한 임의의 RSA / DSA 키는 Windows 파일 시스템에서 사용자의 인식없이 노출되었을 수 있습니다. 귀하의 계정에 액세스 할 수있는 모든 사람이 액세스 할 수 있습니다.
Your disk is being slowly filled with data. Normally not a big concern but it depends on your application (e.g. it might generates hundreds of keys every minute).
To resolve these issues:
using (var rsa = new RSACryptoServiceProvider(1024))
{
try
{
// Do something with the key...
// Encrypt, export, etc.
}
finally
{
rsa.PersistKeyInCsp = false;
}
}
ALWAYS
The RSACryptoServiceProvider(CspParameters)
constructor creates a keypair which is stored in the keystore on the local machine. If you already have a keypair with the specified name, it uses the existing keypair.
It sounds as if you are not interested in having the key stored on the machine.
So use the RSACryptoServiceProvider(Int32)
constructor:
public static void AssignNewKey(){
RSA rsa = new RSACryptoServiceProvider(2048); // Generate a new 2048 bit RSA key
string publicPrivateKeyXML = rsa.ToXmlString(true);
string publicOnlyKeyXML = rsa.ToXmlString(false);
// do stuff with keys...
}
EDIT:
Alternatively try setting the PersistKeyInCsp to false:
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);
rsa.PersistKeyInCsp = false;
string publicPrivateKeyXML = rsa.ToXmlString(true);
string publicOnlyKeyXML = rsa.ToXmlString(false);
// do stuff with keys...
}
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.
참고URL : https://stackoverflow.com/questions/1307204/how-to-generate-unique-public-and-private-key-via-rsa
'IT TIP' 카테고리의 다른 글
Apple Mach-O 링커 경고 "옵션에 대한 디렉토리를 찾을 수 없음…" (0) | 2020.11.19 |
---|---|
Webpack 가져 오기는 가져 오기 순서에 따라 정의되지 않은 것을 반환합니다. (0) | 2020.11.19 |
대다 관계에서 NSPredicate 대소 문자를 구분하지 않는 일치 (0) | 2020.11.19 |
Jquery $ .ajax가 도메인 간 호출에서 IE에서 실패합니다. (0) | 2020.11.19 |
Tkinter :“Python이 Tk 용으로 구성되지 않았을 수 있습니다.” (0) | 2020.11.19 |