Открытый ключ шифрования RSA в C# .NET

Тема в разделе "C++ / C# / .NET", создана пользователем Евгенька, 18 мар 2015.

  1. Гость, давай поддержим форум вместе, делись информацией с друзями через кнопки в блоке "Поделиться в социальных сетях"

    Скрыть объявление
  1. Евгенька

    Евгенька Banned

    
    Регистр:
    20 фев 2015
    Сообщения:
    153
    Лайки:
    192
    Дизлайки:
    0
    Баллы:
    30
    Пол:
    Мужской
    [​IMG]

    В этой статье кратко описывается алгоритм шифрования RSA с открытым ключом а так же приводится пример программы, выполненной в стиле обычного блокнота и демонстрирующей встроенные возможности .NET фреймворка по шифровке и дешифровке RSA. Ниже представлены две функции, позволяющие зашифровать и расшифровать строку символов:
    PHP:
    public string EncryptStringstring inputStringint dwKeySize,
                                 
    string xmlString )
    {
        
    // TODO: Add Proper Exception Handlers
        
    RSACryptoServiceProvider rsaCryptoServiceProvider =
                                      new 
    RSACryptoServiceProviderdwKeySize );
        
    rsaCryptoServiceProvider.FromXmlStringxmlString );
        
    int keySize dwKeySize 8;
        
    byte[] bytes Encoding.UTF32.GetBytesinputString );
        
    // The hash function in use by the .NET RSACryptoServiceProvider here
        // is SHA1
        // int maxLength = ( keySize ) - 2 -
        //              ( 2 * SHA1.Create().ComputeHash( rawBytes ).Length );
        
    int maxLength keySize 42;
        
    int dataLength bytes.Length;
        
    int iterations dataLength maxLength;
        
    StringBuilder stringBuilder = new StringBuilder();
        for( 
    int i 0<= iterationsi++ )
        {
            
    byte[] tempBytes = new byte[
                    ( 
    dataLength maxLength maxLength ) ? maxLength :
                                                  
    dataLength maxLength ];
            
    Buffer.BlockCopybytesmaxLength itempBytes0,
                              
    tempBytes.Length );
            
    byte[] encryptedBytes rsaCryptoServiceProvider.EncrypttempBytes,
                                                                      
    true );
            
    // Обратите внимание, что RSACryptoServiceProvider меняет порядок
            // зашифрованных байт. Он делает это после шифрования и перед
            // дешифровкой. Если Вам не нужна совместимость с Microsoft
            // Cryptographic API (CAPI) или другими поставщиками, то закомментируйте
            // следующую строку и соотвтетствующую строчку в функции DecryptString.
            
    Array.ReverseencryptedBytes );
            
    // Зачем конвертировать в base 64?
            // Потому что это одно из основных печатных оснований использующих только
            // символы ASCII
            
    stringBuilder.AppendConvert.ToBase64StringencryptedBytes ) );
        }
        return 
    stringBuilder.ToString();
    }
    public 
    string DecryptStringstring inputStringint dwKeySize,
                                 
    string xmlString )
    {
        
    // TODO: Add Proper Exception Handlers
        
    RSACryptoServiceProvider rsaCryptoServiceProvider
                                 
    = new RSACryptoServiceProviderdwKeySize );
        
    rsaCryptoServiceProvider.FromXmlStringxmlString );
        
    int base64BlockSize = ( ( dwKeySize ) % != ) ?
          ( ( ( 
    dwKeySize ) / ) * ) + : ( ( dwKeySize ) / ) * 4;
        
    int iterations inputString.Length base64BlockSize;
        
    ArrayList arrayList = new ArrayList();
        for( 
    int i 0iterationsi++ )
        {
            
    byte[] encryptedBytes Convert.FromBase64String(
                 
    inputString.Substringbase64BlockSize ibase64BlockSize ) );
            
    // Обратите внимание, что RSACryptoServiceProvider меняет порядок
            // зашифрованных байт. Он делает это после шифрования и перед
            // дешифровкой. Если Вам не нужна совместимость с Microsoft
            // Cryptographic API (CAPI) или другими поставщиками, то закомментируйте
            // следующую строку и соотвтетствующую строчку в функции EncryptString.
            
    Array.ReverseencryptedBytes );
            
    arrayList.AddRangersaCryptoServiceProvider.Decrypt(
                                
    encryptedBytestrue ) );
        }
        return 
    Encoding.UTF32.GetStringarrayList.ToArray(
                                  
    Type.GetType"System.Byte" ) ) as byte[] );
    }

    Краткое описание шифрования RSA
    Безопасность любой криптографической системы должна быть основана на прочности её основного математического алгоритма. Задача любого криптографического алгоритма, заключается в том, чтобы выдержать испытание временем при его дешифровке. Шифрование RSA названо в честь его изобретателей Рона Ривеста, Ади Шамира и Лена Адлемана (Ron Rivest, Adi Shamir, Len Adleman). Тем не менее, сама идея была впервые исследована в 1973 году членом британского правительства Клиффордом Коксом. На сегодняшний день криптографическая система на основе RSA считается надёжной с длинной ключа в 1024 бита. Причём в ближайшие 3-4 года такая длинна ключа перестанет быть криптостойкой.

    В криптографии, все начинается с данных, которые можно читать без каких-либо дополнительных усилий, то есть "простой-текст". Метод преобразования текста в нечитаемый бред или зашифрованный текст - это и есть шифрование. Процесс возвращения этой тарабарщины обратно в оригинальный текст называется расшифровкой. Проще говоря, криптография, это наука использования математики для шифровки и дешифровки информации. Шифрование позволяет хранить и передавать определённый материал так, что прочесть его сможет только определённый получатель.

    Криптография с открытым ключом использует открытый ключ для шифрования, а соответствующий закрытый ключ для расшифровки. Из-за использования двух различных ключей, её ещё иногда называют асимметричной криптографией. Асимметричность означает несбалансированность или различие. Хотя открытый и закрытый ключи математически связаны, вычислить закрытый ключ из открытого очень трудно, так как это требует факторизации больших простых чисел, и огромного количества вычислительных мощностей. Основное преимущество криптографии с открытым ключом в том, что Вы можете опубликовать ваш открытый ключ, при этом держа закрытый в секрете. Любой человек с копией вашего открытого ключа может зашифровать информацию, которую расшифровать сможете только Вы при помощи закрытого ключа.

    Числа с основанием 64
    В процессе шифрования Вы увидите, что зачастую числа представлены в виде длинный символьных строк. Так, например, модуль, который является частью открытого ключа RSA, может выглядеть следующим образом:
    PHP:
    6nfX01TUfFaliu1wit5RJ5JQNFBzxWSePsviImlPKReIFSjpktWW6RbGk4pNj+fqh2DOWquaMzdXI27YFVuFJQ==
    Это строка символов, на самом деле просто очень большое число, преобразованное в число с основанием 64 (Base-64). Чтобы понять как получаются такие числа, давайте обратимся к элементарной математике. В школе нас учили десятичной системе счисления (с основанием 10):
    PHP:
    Сотни|Десятки|единицы
      1                  9                3
    Таким образом, число "193" состоит из 1-сотни плюс 9-десятков плюс 3-еденицы. Потом мы узнали, что еденицы это 100 , десятки это 101 , а сотни 102 и так далее, поэтому число 193 на самом деле выглядит так:
    PHP:
    { ( 102 ) + ( 101 ) + ( 100 ) }
    Система счисления с основанием 64 (Base-64) работает по такому же принципу, что и десятичная, только в основании используется 64, а не 10. Иными словами, вместо:
    PHP:
    102|101|100
    будет:
    PHP:
    642|641|640
    Так как 64 не получится представить одной десятичной цифрой, то используются буквы
    PHP:
    0-25 это 'A'-'Z'
    26-51 это 'a'-'z'
    52-61 это '0'-'9'
    62 это '+'
    63 это '/'
    64 это '='
    Теперь давайте рассмотрим сам процесс шифрования с открытым ключом. Секретный ключ RSA может иметь два представления. В демонстрационном примере реализован только один вариант, использующий китайскую теорему об остатках. Вот вкратце алгоритм генерации RSA компонентов:

    1. Генерируем два различных больших нечетных простых числа, назовём их P и Q, одинакового порядка, где P больше, чем Q, которые при умножение друг-на-друга дают число с требуемой длинной, например, 1024 бит (полученное число и есть модуль).

    2. Выбираем Экспоненту E, которая больше трёх, и меньше чем, чем модуль - 1. Экспонента не должна быть простой, но она должна быть нечетной. ( P - 1 ) * ( Q - 1 ) не может быть простым, потому что это четное число. Затем убедитесь, что наибольший общий знаменатель экспоненты и наименьшее общее кратное P - 1 и Q - 1 равно 1.

    3. Для создания секретной экспоненты D достаточно просто найти целое число X которое сделает D = (X * ((P - 1) * (Q - 1)) + 1) / E целым, а затем использовать это значение для D.

    4. Следующие ключевые компоненты DP, DQ, и InverseQ находятся по 2 формулам (все компоненты положительные целые числа, где P > Q):
    PHP:
    DP = ( Exponentmod )
    DQ = (Exponent mod )
    InverseQ = ( mod P где P Q
    When representing the plain-text to plain-text octets in order to secure the message more thoroughly it is usual to add padding characters to make it less susceptible to certain types of attack. При представлении текстового для текстовых октетов в целях обеспечения сообщение более тщательно это обычная добавить обивка символы, чтобы сделать его менее восприимчивым к определенным видам атак. I leave this one for your further research. Я оставляю это для ваших дальнейших исследований. After all that has been accomplished you have public and private keys ready for encryption which are then stored as base-64 numbers. После всего, что было достигнуто у вас есть открытый и закрытый ключи готовы для шифрования, которые затем хранятся в базе-64 номеров. The following is a very generalized explanation of the encryption and decryption functions, the cipher is the encryption function and the decipher is the decryption function 2 . Ниже очень обобщенное объяснение шифрования и расшифровки функций, шифр функции шифрования и расшифровки является расшифровка функции 2.
    Функция шифрования:

    C = ( TExponent ) mod Модуль, где C это шифр-текст (целое положительное число), а T - обычный текст (целое положительное число), должен быть меньше модуля.

    Функция Дешифровки:

    T = (CD) mod Модуль, где C это шифр-текст (целое положительное число), T - обычный текст (целое положительное число). D - это секретная экспонента.

    Открытый ключ можно публиковать свободно, поскольку пока нет быстрых методов расчета ваших D, P и Q. В конце статьи Вы можете скачать пример на C#, использующий библиотеки .NET Framework, реализующие RSA шифрование.

    Скачать исходник - 26 кб (кликабельно)

    Скачать демонстрационный пример - 15 кб (кликабельно)