Đây là bài đăng đầu tiên của tôi, vì vậy hy vọng tôi không bỏ lỡ bất kỳ điều gì quan trọng. Tôi đang thực hiện một dự án trong C# nơi tôi cần sử dụng mã hóa khóa công khai/riêng tư để mã hóa một tin nhắn và sau đó gửi nó qua kết nối SSL.Mã hóa RSA của dữ liệu lớn trong C#
Tôi đã chọn sử dụng RSACryptoService
, như theo tài liệu, đó là lược đồ mã hóa không đối xứng duy nhất được sử dụng để mã hóa dữ liệu. Vấn đề là tôi đang gặp rất nhiều vấn đề với điều này. (Tôi muốn làm mã hóa đối xứng, nhưng đó không phải là điều mà giáo viên của tôi muốn tôi làm, và theo anh ta thì dễ dàng chỉ cần xác định kích thước khối và sau đó nó sẽ làm tất cả công việc cho bạn.) Vâng, cho đến nay không có may mắn và tôi đã thử một số cách tiếp cận khác nhau, nhưng bây giờ tôi trở lại vấn đề cơ bản và cố gắng một lần nữa, đây là mã hiện tại của tôi:
public string[] GenerateKeysToStrings(string uniqueIdentifier)
{
string[] keys;
using (var rsa = new RSACryptoServiceProvider(4096))
{
try
{
string privateKey = rsa.ToXmlString(true);
string publicKey = rsa.ToXmlString(false);
this.pki.StoreKey(publicKey, uniqueIdentifier);
keys = new string[2];
keys[0] = privateKey;
keys[1] = publicKey;
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return keys;
}
Như bạn thấy, tôi tạo ra các phím và tôi mimmick một PKI bằng cách gửi khóa công khai đến một lớp đơn giản lưu trữ nó, và sau đó khóa riêng được ghi vào một tệp (Lưu ý rằng tôi cũng có một phương thức khác thực hiện tương tự nhưng lưu trữ nó vào một mảng thay vì chỉ muốn thử nghiệm và đơn giản hóa mọi thứ khi tôi nhận được No such key exceptions
và đôi khi ngoại lệ mã hóa khi tôi thực hiện theo cách được hiển thị trong ví dụ phong phú, vì vậy tôi muốn đơn giản hóa nó bằng cách đơn giản giữ chuỗi rsa.ToXmlString
, như là một chuỗi trong một mảng, nhưng không có may mắn)
Bây giờ tôi có một mã hóa và giải mã phương pháp như sau:.
public string Encrypt(string keyString, string message)
{
string encryptedMessage;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Load the key from the specified path
var encryptKey = new XmlDocument();
encryptKey.Load(@"C:\Test\PrivateKeyInfo.xml");
rsa.FromXmlString(encryptKey.OuterXml);
//// Conver the string message to a byte array for encryption
//// var encoder = new UTF8Encoding();
ASCIIEncoding byteConverter = new ASCIIEncoding();
byte[] dataToEncrypt = byteConverter.GetBytes(message);
byte[] encryptedData = rsa.Encrypt(dataToEncrypt, false);
//// Convert the byte array back to a string message
encryptedMessage = byteConverter.GetString(encryptedData);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return encryptedMessage;
}
Decryption :
public string Decrypt(string keyString, string message)
{
string decryptedText;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Loads the keyinfo into the rsa parameters from the keyfile
/*
var privateKey = new XmlDocument();
privateKey.Load(keyString);
*/
rsa.FromXmlString(keyString);
//// Convert the text from string to byte array for decryption
ASCIIEncoding byteConverter = new ASCIIEncoding();
var encryptedBytes = byteConverter.GetBytes(message);
//// Create an aux array to store all the encrypted bytes
byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, false);
decryptedText = byteConverter.GetString(decryptedBytes);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return decryptedText;
}
tôi biết rằng đây là một bức tường của văn bản, nhưng tôi hy vọng bạn có thể giúp tôi ra vì tôi đã đập đầu tôi vào tường quá lâu bây giờ nó không buồn cười :)
Vấn đề là, làm thế nào để đi về các tin nhắn mã hóa với RSA
(hoặc bất kỳ công/mã hóa khóa bí mật khác)
Đây là khách hàng kiểm tra:
public static void Main(string[] args)
{
PublicKeyInfrastructure pki = new PublicKeyInfrastructure();
Cryptograph crypto = new Cryptograph();
string[] keys = crypto.GenerateKeysToStrings("[email protected]");
string plainText = "Hello play with me, please";
string publicKey = crypto.GetPublicKey("[email protected]");
string encryptedText = crypto.Encrypt(keys[0], plainText);
string decryptedText = crypto.Decrypt(keys[1], encryptedText);
}
Như tôi đã đề cập, các mảng chuỗi đang có vì tôi muốn loại bỏ lỗi phân tích cú pháp xấu khỏi tài liệu XML ...
Khi tôi chạy ứng dụng khách thử nghiệm, nếu tôi sử dụng khóa riêng để mã hóa và khóa công khai để giải mã, tôi sẽ nhận được "Khóa không tồn tại ngoại lệ" và nếu tôi làm điều đó theo cách khác, tôi nhận được một ngoại lệ dữ liệu xấu.
Hãy giúp tôi, nếu bạn biết bất kỳ hướng dẫn hay nào, hoặc có thể cho tôi biết cách thực hiện phần nào mã hóa khóa công khai/riêng tư trên chuỗi tin nhắn, hãy giúp tôi.
Tôi đánh giá cao bất kỳ trợ giúp nào.
Tôi đã nói chuyện với giáo sư của tôi và tại thời điểm đó quan điểm của tôi là tốt hơn nên mã hóa khóa, trao đổi khóa và sau đó sử dụng nó, làm cơ sở cho một thuật toán đối xứng, như rijndael để mã hóa/giải mã thông điệp, tuy nhiên, anh ta không muốn chúng tôi sử dụng mã hóa đối xứng vì vậy bây giờ tôi đang ở vị trí hiện tại đang bị hạn chế. Hiệu năng khôn ngoan, mất bao nhiêu thời gian để mã hóa tin nhắn, 501 byte một lần (sử dụng các khóa RSA 4096bit) khi chúng ta nói về các thông điệp HTTP có chứa tên người dùng và mật khẩu? mã hóa khối theo khối hay không, tôi vẫn có vấn đề thực sự bằng cách sử dụng RSA: ( –
Bạn có thể lặp mã hóa/giải mã RSA để ở dưới giới hạn kích thước (bao gồm đệm) và ghép/chia kết quả. CPU của bạn, nó là một điện thoại thông minh cũ và một máy chủ 8 lõi mới? ;-) nhưng dài hơn rất nhiều so với một giải pháp thay thế chính xác. – poupou
Tôi ước mình có thể có thời gian, nhưng ngay bây giờ tôi thậm chí không thể làm điều này để làm việc cho bất kỳ dữ liệu nào. Tôi lấy một phiên bản đơn giản và sử dụng nó, tuy nhiên, tôi vẫn nhận được lỗi "Key không tồn tại" và tất cả những gì tôi thực sự làm là cấu trúc lại thiết kế, từ một phương thức chính đến các phương thức riêng biệt. Có lẽ tôi đang sử dụng hàm tạo phải không? Phần mà tôi nhập cài đặt khóa? Tôi biết rằng mật mã khối chậm hơn 1000 lần so với thuật toán đối xứng, nhưng ngay bây giờ tôi chỉ muốn nó hoạt động, cho dù tôi có phải mã hóa nó để tôi cắt từng khối dữ liệu thành các phần (keyize/8 - 11 (cho đệm)) byte. –