Покорение RSA на C#
Ранее я разработал компоненту на C# для подключения терминала с биометрией Anviz к 1С. Но я сделал ее для единственного клиента. А для того, чтобы ее можно было использовать для большого количества клиентов, нужно сделать проверку серийного номера.
Для проверки я ранее использовал RSA, но это было на Visual Basic. Код проверки выглядел примерно так:
Function CheckLicense(Serial) Dim i As Long Dim CurrLic As String Dim CurrSerial As String Dim CurrMask As String Dim strDeCrypt As String CheckLicense = False 'By default On Error GoTo errtrap For i = LBound(SerialsLicens) To UBound(SerialsLicens) CurrLic = SerialsLicens(i) CurrSerial = Left(CurrLic, 16) 'Seek for serial 'MsgBox "Curr serial: " & CurrSerial If CurrSerial = Serial Then CurrMask = Mid(CurrLic, 18) 'MsgBox "Curr mask: " & CurrMask 'if already checked before If CurrMask = "+" Then CheckLicense = True Exit Function Else strDeCrypt = mpModExp(CurrMask, PublicKeyExp, PublicKeyModulus) 'MsgBox "Decrypt: " & strDeCrypt If Val(strDeCrypt) = Val(CurrSerial) Then CheckLicense = True SerialsLicens(i) = CurrSerial & ":+" 'MsgBox "Memory for serial: " & SerialsLicens(i) Exit Function Else Exit Function End If End If End If Next Exit Function errtrap: MsgBox "Error CheckLicense:" & err.Description & " " & err.HelpContext End Function
Публичный ключ состоял из степени PublicKeyExp и модуля PublicKeyModulus. Предварительно я проверял корректность самого публичного ключа. И потом восстанавливал публичным ключом зашифрованную лицензию. Если восстанавливался серийный номер, равный текущему, значит проверка прошла.
Мои первые шаги в C# в RSA были неуклюжими.
Конечно в Microsoft есть готовый RSA-класс для шифрования, но он очень усложнен, я не понял, как им пользоваться.
Поэтому я нашел готовый пример программы RSA-шифрования, использующую класс Biginteger.
Сначала я перенес свой проект в другой каталог и не мог найти, где указать, какой из двух проектов сборки должен запускаться (один проект — библиотека, другой — тестовая форма). В итоге нашел:
Следующей проблемой оказалось то, что C# ругался на Biginteger. Я нашел, что нужно подключить библиотеку Numeric. Но она не подключалась. Нашел, что потому, что у меня сборка под Net 2.0, а надо под Net 4.0. Поменял целевую платформу, все заработало:
Возникла очередная проблема — я не знал, как в C# добавлять модули для библиотечных функций. Но примерно понимал, что их можно заменить static-классами. Нашел пример static-классов. Сделал по аналогии:
using System; using System.Collections.Generic; using System.Numerics; using System.Text; namespace AnvizCCH { static public class myRSA { static public string RSA_Decode(string input, long d, long n) { string result = ""; //About hex: https://stackoverflow.com/questions/30119174/converting-a-hex-string-to-its-biginteger-equivalent-negates-the-value BigInteger bi = BigInteger.Parse("0" + input, System.Globalization.NumberStyles.AllowHexSpecifier); bi = BigInteger.Pow(bi, (int) d); BigInteger n_ = new BigInteger((int)n); bi = bi % n_; result = bi.ToString(); return result; } } }
Нашел один небольшой нюанс, что в начало числа надо добавлять ноль, чтобы не получать отрицательных значений Biginteger.
У меня еще была особенность в том, что я использую шестнадцатеричные значения чисел. Поэтому пришлось решать и эту проблему.
В итоге у меня получилось сделать первые шаги в декодировании закодированного ключа и я наполнился оптимизмом, что смогу решить эту задачу — основные препоны остались позади.
>Конечно в Microsoft есть готовый RSA-класс для шифрования, но он очень усложнен, я не понял, как им пользоваться.
>Поэтому я нашел готовый пример программы RSA-шифрования, использующую класс Biginteger.
как всегда глобально и надежно 🙂
У тебя есть способ решения проблемы? Я читал про Микрософтовский RSA, что он не умеет шифровать открытым ключом, например. Просто подумали, что это не нужно.
google://.net rsa example
вторая ссылка на stackoverflow с подробным примером
Я, кстати, видел этот пост, вы же про этот?
Только мне он ничего не подсказал по теме, почему RSA не расшифровывает.
У Микрософт, как всегда, плохо с диагностикой ошибок.
В смысле «он не умеет шифровать открытым ключом»?
RSA (аббревиатура от фамилий Rivest, Shamir и Adleman) — криптографический алгоритм с открытым ключом
Я не про RSA в целом, а про его реализацию от Microsoft в NET.
Видел где-то в обсуждениях, была проблема шифровать открытым ключом. Закрытым — проблем нет. Но иногда надо наоборот.
но ведь закрытый ключ используется только для дешифрации ))))
нет. Бывают разные ситуации.
Например, если нужно проверить корректность подписи, то шифруем закрытым.
если нужно передать в целостности, то открытым.
Только уже это не шифрование
А что это по-вашему? Только без буквоедства.
Что?