Поиск на сайте
Главная Журнал Форум Wiki DRKB Страны мира

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

RSACryptoPad пример открытого ключа шифрования RSA

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

public string EncryptString( string inputString, int dwKeySize, 
                             string xmlString )
{
    // TODO: Add Proper Exception Handlers
    RSACryptoServiceProvider rsaCryptoServiceProvider = 
                                  new RSACryptoServiceProvider( dwKeySize );
    rsaCryptoServiceProvider.FromXmlString( xmlString );
    int keySize = dwKeySize / 8;
    byte[] bytes = Encoding.UTF32.GetBytes( inputString );
    // 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; i <= iterations; i++ )
    {
        byte[] tempBytes = new byte[ 
                ( dataLength - maxLength * i > maxLength ) ? maxLength : 
                                              dataLength - maxLength * i ];
        Buffer.BlockCopy( bytes, maxLength * i, tempBytes, 0, 
                          tempBytes.Length );
        byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt( tempBytes,
                                                                  true );
        // Обратите внимание, что RSACryptoServiceProvider меняет порядок 
        // зашифрованных байт. Он делает это после шифрования и перед 
        // дешифровкой. Если Вам не нужна совместимость с Microsoft 
        // Cryptographic API (CAPI) или другими поставщиками, то закомментируйте
        // следующую строку и соотвтетствующую строчку в функции DecryptString.
        Array.Reverse( encryptedBytes );
        // Зачем конвертировать в base 64?
        // Потому что это одно из основных печатных оснований использующих только 
        // символы ASCII
        stringBuilder.Append( Convert.ToBase64String( encryptedBytes ) );
    }
    return stringBuilder.ToString();
}
 
public string DecryptString( string inputString, int dwKeySize, 
                             string xmlString )
{
    // TODO: Add Proper Exception Handlers
    RSACryptoServiceProvider rsaCryptoServiceProvider
                             = new RSACryptoServiceProvider( dwKeySize );
    rsaCryptoServiceProvider.FromXmlString( xmlString );
    int base64BlockSize = ( ( dwKeySize / 8 ) % 3 != 0 ) ?
      ( ( ( dwKeySize / 8 ) / 3 ) * 4 ) + 4 : ( ( dwKeySize / 8 ) / 3 ) * 4;
    int iterations = inputString.Length / base64BlockSize; 
    ArrayList arrayList = new ArrayList();
    for( int i = 0; i < iterations; i++ )
    {
        byte[] encryptedBytes = Convert.FromBase64String( 
             inputString.Substring( base64BlockSize * i, base64BlockSize ) );
        // Обратите внимание, что RSACryptoServiceProvider меняет порядок 
        // зашифрованных байт. Он делает это после шифрования и перед 
        // дешифровкой. Если Вам не нужна совместимость с Microsoft 
        // Cryptographic API (CAPI) или другими поставщиками, то закомментируйте
        // следующую строку и соотвтетствующую строчку в функции EncryptString.
        Array.Reverse( encryptedBytes );
        arrayList.AddRange( rsaCryptoServiceProvider.Decrypt( 
                            encryptedBytes, true ) );
    }
    return Encoding.UTF32.GetString( arrayList.ToArray( 
                              Type.GetType( "System.Byte" ) ) as byte[] );
}

Краткое описание шифрования RSA

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

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

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

Числа с основанием 64

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

6nfX01TUfFaliu1wit5RJ5JQNFBzxWSePsviImlPKReIFSjpktWW6RbGk4pNj+fqh2DOWquaMzdXI27YFVuFJQ==

Это строка символов, на самом деле просто очень большое число, преобразованное в число с основанием 64 (Base-64). Чтобы понять как получаются такие числа, давайте обратимся к элементарной математике. В школе нас учили десятичной системе счисления (с основанием 10):

Сотни|Десятки|еденицы
  1      9       3

Таким образом, число "193" состоит из 1-сотни плюс 9-десятков плюс 3-еденицы. Потом мы узнали, что еденицы это 100 , десятки это 101 , а сотни 102 и так далее, поэтому число 193 на самом деле выглядит так:

{ ( 1 * 102 ) + ( 9 * 101 ) + ( 3 * 100 ) }

Система счисления с основанием 64 (Base-64) работает по такому же принципу, что и десятичная, только в основании используется 64, а не 10. Иными словами, вместо:

102|101|100

будет:

642|641|640

Так как 64 не получится представить одной десятичной цифрой, то используются буквы:

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):

  • DP = ( 1 / Exponent) mod ( P - 1 )
  • DQ = (1 / Exponent ) mod ( Q - 1 )
  • InverseQ = ( 1 / Q ) 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 кб




Основные разделы сайта


 

Реклама