Как защитить серийник при помощи RSACryptoServiceProvider
От: H.P. Baxxter  
Дата: 03.06.06 10:14
Оценка:
sn должен шифроваться закрытым ключом, и дешифроваться открытым непосредственно при активации. Это возможно при помощи RSACryptoServiceProvider — у меня он ну никак не хочет шифровать закрытым ключом, только открытым. ??? Можно ли поставленную задачу решить средствами FCL без собственной реализации RSA?
Как защитить серийник при помощи RSACryptoServiceProvider
От: Аноним  
Дата: 03.06.06 18:49
Оценка: 1 (1)
Как необычно.. Обычно шифруют открытым ключом, а закрытым либо дешифруют, либо подписывают.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Как защитить серийник при помощи RSACryptoServiceProvide
От: H.P. Baxxter  
Дата: 05.06.06 10:58
Оценка:
Здравствуйте, Smorn, Вы писали:

S>Как необычно.. Обычно шифруют открытым ключом, а закрытым либо дешифруют, либо подписывают.


S>
данное сообщение получено с www.gotdotnet.ru

S>ссылка на оригинальное сообщение


Согласен, но мне нужно шифровать именно закрытым, подпись не походит т.к. подписывается хеш.
Re: Как защитить серийник при помощи RSACryptoServiceProvide
От: Аноним  
Дата: 05.06.06 12:18
Оценка:
Нет, я не знаю явного способа заставить RSACryptoServiceProvider шифровать информацию закрытым ключом, кроме неявных SignData/SignHash.
Просто интересно, а почему именно такая постановка задачи? Смысл шифрования закрытым ключом состоит в том, чтобы позволить любому ее дешифроваить, т.е. информация не прячется, просто предоставляется способ проверки ее подлинности и целостности, что и есть цифровая подпись. В чем тогда секретность и зачем вообще шифровать sn, если каждый может его расшифровать? Далее, так или иначе, понадобиться ключ, а если есть возможность его прятать до определенного момента, то не проще ли будет воспользоваться симметричным алгоритмом?



данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Как защитить серийник при помощи RSACryptoServiceProvide
От: Andir Россия
Дата: 05.06.06 12:28
Оценка:
Здравствуйте, H.P. Baxxter, Вы писали:

HPB>sn должен шифроваться закрытым ключом, и дешифроваться открытым непосредственно при активации. Это возможно при помощи RSACryptoServiceProvider — у меня он ну никак не хочет шифровать закрытым ключом, только открытым. ??? Можно ли поставленную задачу решить средствами FCL без собственной реализации RSA?


Для RSA нет никакой разницы какой из ключей считается открытм, а какой закрытым. Это условное деление.

C Уважением, Andir!
using( RSDN@Home 1.2.0 alpha rev. 651 ) { /* Работаем */ }
Re: Как защитить серийник при помощи RSACryptoServiceProvide
От: Аноним  
Дата: 05.06.06 14:12
Оценка: 1 (1)
>> Для RSA нет никакой разницы какой из ключей считается открытм, а какой закрытым. Это условное деление.
Не могу с этим согласиться. Эти ключи вычисляются по-разному, у них разная структура хранения, а это, в свою очередь, дает возможность получить открытый ключ по закрытому, в то время как на невозможности/сложности обратного процесса и основан RSA. Более того, раз уж выбор, что есть public или private делается классом за нас, мы обязаны считать открытым(закрытым) именно тот ключ, который считаеся открытым(закрытым) этим самым классом.
Далее, и что особенно важно в данной задаче, когда используется термин закрытый ключ, имеется ввиду охраняемый секрет, доступный только одному. Поэтому здесь проблема видится не столько вычислительной, сколько смысловой.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: H.P. Baxxter  
Дата: 06.06.06 08:05
Оценка:
Здравствуйте, Smorn, Вы писали:


S>Просто интересно, а почему именно такая постановка задачи?


Шифрование моим секретным ключом sn не позволить создать keygen, даже если алгоритм генерации sn известен. Подпись не подходит, т.к. по ней серийник не востановишь из-за хеширования — придется распостранять sn + подпись...
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: Аноним  
Дата: 06.06.06 20:28
Оценка:
Зачем шифровать понятно, непонятно почему это нужно делать закрытым ключом.

Anyway, FYI (RSA Encryption, 1.5):
Application of private-key operations as defined here to data other than an octet string containing a message digest is not recommended and is subject to further study.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: Streamer1 Украина  
Дата: 06.06.06 20:33
Оценка:
Здравствуйте, H.P. Baxxter, Вы писали:

S>>Как необычно.. Обычно шифруют открытым ключом, а закрытым либо дешифруют, либо подписывают.


S>>
данное сообщение получено с www.gotdotnet.ru

S>>ссылка на оригинальное сообщение


HPB>Согласен, но мне нужно шифровать именно закрытым, подпись не походит т.к. подписывается хеш.


а ты считай что закрытый ключ — это открытый, а открытый — это закрытый
Тот кто говорит не знает, тот кто знает не говорит.
Как защитить серийник при помощи RSACryptoServiceProvide
От: Streamer1 Украина  
Дата: 06.06.06 22:10
Оценка: 24 (5)
#Имя: FAQ.dotnet.RSACrypto.keygen
Здравствуйте, H.P. Baxxter, Вы писали:

HPB>sn должен шифроваться закрытым ключом, и дешифроваться открытым непосредственно при активации. Это возможно при помощи RSACryptoServiceProvider — у меня он ну никак не хочет шифровать закрытым ключом, только открытым. ??? Можно ли поставленную задачу решить средствами FCL без собственной реализации RSA?


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

по поводу надежных серийников — можно реализовывать так:

1. Разработчик формирует пару ключей открытый/закрытый: publicKey/privateKey
publicKey встраивается в софтину, privateKey в кейген, причем последний нежно прижимая к груди прячет в сейф...

  private static string publicKey  = @"<RSAKeyValue><Modulus>s2nF3YcI+jaRcdtfWbVmkWbN2own5Jb4XOLbvwZYMqTLZA40rn2CVRj//66N2La+ay8Zg0Hjil7hXZGkC0ujTYecdGhPnyAH7TC3A7Ksz+kg2z32N5vgk+ZpVIiU+9wi83fsD5Ojk8QuTlYiQpyxWI66d5h6I7BoWmhnmeM2YPk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
  private static string privateKey  = @"<RSAKeyValue><Modulus>s2nF3YcI+jaRcdtfWbVmkWbN2own5Jb4XOLbvwZYMqTLZA40rn2CVRj//66N2La+ay8Zg0Hjil7hXZGkC0ujTYecdGhPnyAH7TC3A7Ksz+kg2z32N5vgk+ZpVIiU+9wi83fsD5Ojk8QuTlYiQpyxWI66d5h6I7BoWmhnmeM2YPk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";



2. Разработчик самоуверенно вводит такой текст в кейгене:

Product=Super Puper Mega Software System
LicenseType=FULL
MegaAddress=http://www.supermegasoft.medved.preved.net
UserName=Медвед


3. Кейген подписывает текст с помощью закрытого ключа и получается такой текст:

Product=Super Puper Mega Software System
LicenseType=FULL
MegaAddress=http://www.supermegasoft.medved.preved.net
UserName=Медвед
SuperPuperSignature=DKGEA8FVCEC3CHGIENFRCDFQDOFTE9GRB9AECIENAIEKGHCYABA8ECEUB5GSE1AQBOCCFRBZENAODYBQEUCBCYCEACE0DGFJE7BZG4DOEYEMF2D3G2B3BPB0BKG4C7EMGHDHB8D1FOF8FMF0BDBYEHENGJE4GED8CIGMCNFPE0ETFFCUCPA6BPBPF6CADKFCERAGF0AEEIB5AGGBA8CHGHESGJBVGYDJDJEJFIBEAAGLGQA5AICCE0AVDRFWCOGE


4. Кейген заворачивает весь этот текст в сериал нумбер, примерно такого содержания:

{CIEXADGACIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAC7
ACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB
9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJA
AB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB
7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AA
BCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5
AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAA
B8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACP
AAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AA
CJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5
AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB
7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEA
AB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AAC
FAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5A
ACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB
6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIA
AB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACL
AAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AA
CEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9
AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAA
B5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AABCIAAB5AAB7AAB6AACJAAB5AACPAAB9AACFAAB8AACEAAB5AACLAAB7AAB9AABTAAB7A
AB9AAB7AAB8AAB3AACOAAB3AACFAAB7AACAAAB3AACPAAB3AAB3AAB8AABSAAAKAA}


5. Разработчик высокомерно продает полученную абракадабру за вожделенную денюжку



Что происходит у юзверя:

1. Юзверь расставшись с денюжкой некоторое время горюет и оплакивает их крокодиловыми слезами, потом наконец успокаивается и вводит сериал нумбер в софтине

2. Софтина раскручивает абракадабру в текст:

Product=Super Puper Mega Software System
LicenseType=FULL
MegaAddress=http://www.supermegasoft.medved.preved.net
UserName=Медвед
SuperPuperSignature=DKGEA8FVCEC3CHGIENFRCDFQDOFTE9GRB9AECIENAIEKGHCYABA8ECEUB5GSE1AQBOCCFRBZENAODYBQEUCBCYCEACE0DGFJE7BZG4DOEYEMF2D3G2B3BPB0BKG4C7EMGHDHB8D1FOF8FMF0BDBYEHENGJE4GED8CIGMCNFPE0ETFFCUCPA6BPBPF6CADKFCERAGF0AEEIB5AGGBA8CHGHESGJBVGYDJDJEJFIBEAAGLGQA5AICCE0AVDRFWCOGE


3. Софтина убирает строчку с SuperPuperSignature и проверяет подлинность оставшегося текста с помощью открытого ключа в теле программы и подписи из SuperPuperSignature, если текст оказался подлиным он юзается для разблокировки софта в нужный режим, а юзверь счастливо улыбается увидев заветную надпись "Поздравляем!!! Супермегасофт система зарегистрирована для юзверя: Медвед"

Алгоритмы заворачивания/разворачивания текста и ключа в ASCII абракадабру:
      private static string alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

// заворачивание:
      public static string EncodeLicenseKey(string licenseKey, bool split)
      {
         return ("{" + Encode(Encoding.Unicode.GetBytes(licenseKey), split) + "}");
      }

      public static string Encode(byte[] bytes, bool split)
      {
         StringBuilder builder = new StringBuilder();
         if (bytes != null)
         {
            for (int i = 0; i < bytes.Length; i++)
            {
               if ((split && ((i % 0x20) == 0)) && (i > 0))
               {
                  builder.Append("\r\n");
               }
               builder.Append(alphabet[bytes[i] / alphabet.Length]);
               builder.Append(alphabet[bytes[i] % alphabet.Length]);
            }
         }
         return builder.ToString();
      }

// разворачивание:
      public static string DecodeLicenseKey(string text)
      {
         StringBuilder builder = new StringBuilder();
         bool flag = false;
         for (int i = 0; i < text.Length; i++)
         {
            if (!flag && (text[i] == '{'))
               flag = true;
            else
            {
               if (text[i] == '}')
                  break;
               if (alphabet.IndexOf(text[i]) != -1)
                  builder.Append(text[i]);
            }
         }
         return Encoding.Unicode.GetString(Decode(builder.ToString()));
      }

      public static byte[] Decode(string text)
      {
         if (text == null)
         {
            text = string.Empty;
         }
         byte[] buffer = new byte[text.Length / 2];
         for (int i = 0; i < (buffer.Length * 2); i += 2)
         {
            buffer[i / 2] = (byte)((alphabet.IndexOf(text[i]) * alphabet.Length) + alphabet.IndexOf(text[i + 1]));
         }
         return buffer;
      }


Проверка подписи производится так:
      public static bool CheckLicenseSign(string licenseText, string signText, string publicKey)
      {
         byte[] buffer1 = Decode(signText);
         RSACryptoServiceProvider provider = new RSACryptoServiceProvider(0x400);
         provider.FromXmlString(publicKey);
         byte[] buffer2 = Encoding.Unicode.GetBytes(licenseText);
         SHA1 sha = new SHA1CryptoServiceProvider();
         byte[] buffer3 = sha.ComputeHash(buffer2);
         RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(provider);
         deformatter.SetHashAlgorithm("SHA1");
         return deformatter.VerifySignature(buffer3, buffer1);
      }


Подпись в кейгене производится так:
   private void buttonSign_Click(object sender, EventArgs e)
   {
// ....<skip>...
      licenseText = GetSuperLicenseText(collection);

      byte[] buffer2 = Encoding.Unicode.GetBytes(licenseText);
      RSACryptoServiceProvider myprov = new RSACryptoServiceProvider(0x400);
      myprov.FromXmlString(privateKey);
      SHA1 sha1 = new SHA1CryptoServiceProvider();
      byte[] buffer3 = sha1.ComputeHash(buffer2);

      RSAPKCS1SignatureFormatter formatter1 = new RSAPKCS1SignatureFormatter(myprov);
      formatter1.SetHashAlgorithm("SHA1");
      byte[] buffer1 = formatter1.CreateSignature(buffer3);

      string mysign = Encode(buffer1, false);        // получили подпись

      licenseLines.Add("SuperPuperSignature=" + mysign);        // добавили строчку с подписью

// ...<skip>
   }


писалось все это весьма давно, так что чтото мог и забыть, но вроде все описал...

подбор ключа имхо невозможен, шифровать ничё не надо
так что не заморачивайтесь

P.S.: все имена, названия, public/private ключи вымышленные, ключи юзабельные но нигде не использовались, сериал формировался Copy/Paste мусора, более подробно описывать лень...
Тот кто говорит не знает, тот кто знает не говорит.
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: Streamer1 Украина  
Дата: 07.06.06 09:52
Оценка:
забыл упомянуть что программа сохраняет не "Registered=true", а сам сериал нумбер, который проверяется для создании экземпляра License при каждом запуске.

Весь код проверки вместе с publicKey и кодом License и всего связанного с ним лежит в отдельной сборке, в которую также складываются все ключевые базовые классы, часть кода сборки делается на нативном коде, сборка подписывается strong name, все остальные сборки также подписываются и все ссылаются на эту ключевую сборку по строгому имени...

Таким образом, для изменения publicKey необходимо декомпилировать и перекомпилить ключевую сборку, что приведет к необходимости декомпилировать и перекомпилить все сборки проекта, а отдекомпилить ключевую сборку проблематично, т.к. в ней юзается нативный код...

а без подстановки своего publicKey (для кот. известен privateKey) в эту ключевую сборку, подписать текст лицензии с настройками невозможно...

сам текст лицензии абракадабрируется только для того чтобы юзвери c длинным носом не пытались подменить чтото, т.к. это может повлечь шквал звонков в поддержку с проблемой восстановления работоспособности системы...
Тот кто говорит не знает, тот кто знает не говорит.
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: H.P. Baxxter  
Дата: 07.06.06 16:03
Оценка:
спс, буду писать под такую схему...
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: Аноним  
Дата: 10.07.06 07:29
Оценка:
Схема не понравилась.
Серийник расшарить можно.



данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: Аноним  
Дата: 11.07.06 01:42
Оценка:
ak

Ты знаешь схему лучше? Обычно все действуют по такой схеме, если попадается расшаренный серийник, его банят.

Единственный минус данного метода в том что для убирания стронгнейма не обязательно декомпилировать\компилировать

------
Форум профессионалов


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Как защитить серийник при помощи RSACryptoServiceProv
От: Аноним  
Дата: 11.07.06 07:22
Оценка:
У меня другая схема, но она, к сожалению, также не идеальна и под нее кейген можно соорудить
Хотелось бы придумать более оптимальный алгоритм...


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.