RSA Шифрование больших данных в C # - PullRequest
7 голосов
/ 07 декабря 2011

Это мой первый пост, так что надеюсь, я не пропустил ничего важного. Я делаю проект на C #, где мне нужно использовать шифрование с открытым / закрытым ключом, чтобы зашифровать сообщение и затем отправить его через соединение SSL.

Я решил использовать RSACryptoService, поскольку, согласно документации, это была единственная асимметричная схема шифрования, используемая для шифрования данных. Проблема в том, что у меня много проблем с этим. (Я хотел сделать симметричное шифрование, но это не то, чего хочет от меня мой учитель, и, по его словам, должно быть просто определить размер блока, и тогда он должен сделать всю работу за вас.) Ну, пока что не повезло, и я попробовал несколько разных подходов, но теперь я возвращаюсь к основам и пытаюсь снова, это мой текущий код:

    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;
    }

Как видите, я генерирую ключи и подражаю PKI, отправляя открытый ключ в простой класс, который его хранит, а затем закрытый ключ записывается в файл (Обратите внимание, что у меня также есть другой метод, который делает то же самое, но сохраняет его в массиве, просто потому, что я хотел протестировать и упростить вещи, когда получаю No such key exceptions и иногда криптографические исключения, когда я делаю это так, как показано в примере, поэтому я хотел упростить его, просто сохранив строку rsa.ToXmlString как строку в массиве, но не повезло.)

Теперь у меня есть метод шифрования и дешифрования следующим образом:

    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;
    }

дешифрование:

    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;
    }

Я знаю, что это стена текста, но я надеюсь, что вы можете помочь мне, потому что я так долго бился головой о стену, что теперь это не смешно :)

Проблема в том, как мне шифровать сообщения с помощью RSA (или любого другого шифрования с открытым / закрытым ключом)

Вот тестовый клиент:

    public static void Main(string[] args)
    {
        PublicKeyInfrastructure pki = new PublicKeyInfrastructure();
        Cryptograph crypto = new Cryptograph();
        string[] keys = crypto.GenerateKeysToStrings("simonlanghoff@gmail.com");


        string plainText = "Hello play with me, please";
        string publicKey = crypto.GetPublicKey("simonlanghoff@gmail.com");

        string encryptedText = crypto.Encrypt(keys[0], plainText);


        string decryptedText = crypto.Decrypt(keys[1], encryptedText);

    }

Как я уже говорил, строковые массивы существуют потому, что я хотел устранить ошибку синтаксического анализа в документах XML ...

Когда я запускаю тестовый клиент, если я использую закрытый ключ для шифрования и открытый ключ для дешифрования, я получаю «Исключение ключа не существует», и если я делаю это наоборот, я получаю исключение для неверных данных .

Пожалуйста, помогите мне, ребята, если вы знаете какое-нибудь хорошее руководство или можете подсказать, как несколько проще реализовать шифрование с открытым / закрытым ключом для строковых сообщений, пожалуйста, помогите мне.

Я ценю любую помощь.

Ответы [ 3 ]

5 голосов
/ 07 декабря 2011

Это не то, как должно выполняться шифрование RSA.

RSA - это математика.То, что вы шифруете, это число, поэтому оно должно быть конечной длины и соответствовать длине пары ключей RSA, которую вы используете.Дальнейшие ограничения по длине накладываются используемым заполнением (либо PKCS # 1, либо OAEP).

Если вы хотите зашифровать большие данные с помощью RSA, вам нужно сделать это косвенно - то есть использовать симметричный ключ для шифрования больших данныхи зашифруйте этот ключ с помощью открытого ключа RSA.

О его реализации вы можете прочитать в моем блоге .

1 голос
/ 08 декабря 2011

Хорошо, я наконец-то нашел решение проблемы, о которой говорил в своем первоначальном сообщении.Это то, что я не проверял полностью или что-то в этом роде, но кое-что я понял из небольшого процесса проб и ошибок.

Вот текущий код, который у меня есть:сказал, что я не проверял это много, кроме размеров ниже, в и выше размера блока, но, кажется, делает то, что должен.Я все еще новичок, поэтому мне бы очень хотелось, чтобы вы внимательно изучили мой код:)

0 голосов
/ 07 декабря 2011

Возможно, я что-то упускаю, но похоже, что ваша функция Encrypt () не использует ни параметр keyString, ни содержимое encryptKey.

...