2013-04-28 5 views
1

У меня есть следующий код C#:C# - Шифрование и использование дешифрование данных RSA

главный класс

X509Certificate2 cert = new X509Certificate2("C:/test.pfx", "hello", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); 

      Encryption enc = new Encryption(); 
      string encrypted = enc.Encrypt("hello there", cert); 
      string decrypted = enc.Decrypt(encrypted, cert); 
      Console.WriteLine("Encrypted Text: " + encrypted); 
      Console.WriteLine("Decrypted Text: " + decrypted); 

Encryption Class

public string Encrypt(string plainText, X509Certificate2 cert) 
{ 
    RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; 
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText); 
    byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false); 
    string encryptedText = encryptedBytes.ToString(); 
    return encryptedText; 
} 

public string Decrypt(string encryptedText, X509Certificate2 cert) 
{ 
    RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey; 
    byte[] encryptedBytes = Encoding.UTF8.GetBytes(encryptedText); 
    byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false); 
    string decryptedText = decryptedBytes.ToString(); 
    return decryptedText; 
} 

Как вы можете видеть, в основном классе я импортирую сертификат. Затем я создаю экземпляр класса Encryption. Затем я передаю открытый текст методу шифрования вместе с сертификатом, чтобы получить зашифрованный текст. Впоследствии я передаю зашифрованный текст в метод Decrypt, чтобы вернуть текст обратно.

Моя проблема заключается в том, что результатом печати зашифрованного текста является System. [] Byte (если я прокомментирую вызов дешифрования). Если я не закомментирую вызов дешифрования, я получаю криптографическое исключение: плохие данные в методе дешифрования.

Я предполагаю, что массив encryptedBytes неверно преобразован в строку. Кроме того, я не уверен, правильно ли я формирую RSAEncryptionProvider. Как я могу решить это, пожалуйста?

Update

Я решил одну проблему. При преобразовании из массива байтов в строку мне пришлось использовать Encoding.UTF8.GetString (EncryptedBytes). Теперь проблема заключается в том, что метод дешифрования дает мне другое криптографическое исключение (его данные, подлежащие расшифровке, превышают максимальный для этого модуля 128 байт).

Кто-нибудь знает, почему это происходит и как его решить?

+1

Шифрование всегда делается на двоичных данных (хотя это может выглядеть как строка для вас) и всегда производит двоичные данные в качестве выходных данных. Почему вы ожидаете каких-либо строк? –

+0

Не повторяйте теги в заголовках. –

+0

@Eugene Я хочу отобразить текст на экране, чтобы увидеть, действительно ли он работает – Matthew

ответ

2

Не обрабатывайте зашифрованные данные как строку. Алгоритмы шифрования работают с двоичными данными и производят двоичные данные, которые нельзя интерпретировать как строку. Наивно полагать, что UTF-8 или любая другая кодировка смогут интерпретировать любой заданный фрагмент двоичных данных как допустимую строку символов.

В вашем случае, если вам нужно выводить зашифрованы данные на консоль для отладки, идти вперед с byte[] и сбросить его в шестнадцатеричном формате, например:

for (int i = 0; i < data.Length; i++) 
{ 
    Console.Write(data[i].ToString("X2")); 
    Console.Write(" "); 
    if ((i+1) % 16 == 0) Console.WriteLine(); 
} 
+0

Но как вы используете шифрование RSA, если вы хотите передать зашифрованные байт [] данные с сервера A (Windows) на другой сервер B, работающий на Linux? – Legends

+0

@Legends Используемая вами операционная система * не имеет значения * в отношении того, как работает шифрование. –

+0

Я хотел сказать, что Мэтью сказал это в комментарии: >> Я хочу отобразить текст на экране, чтобы увидеть, действительно ли он работает << Итак, это было его намерение отобразить текст, чтобы увидеть, его функции enc/dec работают: Но вы сказали, что двоичные данные не могут быть интерпретированы как строка. И это неправильно, или вы имели в виду что-то еще? Пример: 'var cert = getC(); RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) cert.PublicKey.Key; byte [] cipherData = rsa.Encrypt (Encoding.UTF8.GetBytes (plainData), _onlyValidCerts); return Convert.ToBase64String (cipherData); ' – Legends

1

вы можете использовать base64 формат для преобразования типа переменного параметра (encryptedText) путем замены функции

public string Encrypt(string plainText, X509Certificate2 cert) 
{ 
    RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; 
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText); 
    byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false); 
    string encryptedText = Convert.ToBase64String(encryptedBytes); 
    return encryptedText; 
} 

public string Decrypt(string encryptedText, X509Certificate2 cert) 
{ 
    RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey; 
    byte[] encryptedBytes = Convert.FromBase64String(encryptedText); 
    byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false); 
    string decryptedText = Encoding.UTF8.GetString(decryptedBytes); 
    return decryptedText; 
} 
Смежные вопросы