Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Кто работал с CryptoAPI Помогите

Разбираюсь с  CryptoAPI шифровать и дешифровать научился. А вот экспортировать и импортировать сессионный ключ не могу. Весь интернет излазил сорцы с ошибками, кто работал с  CryptoAPI помогите изучить шифрование файлов.
Ответ:
Большое спасибо все работает. Очень помогли. Теперь меняю  пробую и изучаю. Еще одна просьба где можно по лучше прочитать про "CryptDeriveKey" функция которая при одинаковых входных данных генерирует один и тот же пароль. 
Вопрос: Lazarus CryptoAPI пара вопросов.

Работа с CryptoAPI используя модуль JwaWinCrypt.
Имеются открытые ключи, из них надо получить информацию:
Срок действия
Кому выдан
Кем выдан
Улучшенный ключ

По первым 3-м пунктам все хорошо, а вот где найти информацию как достать значение "Улучшенный ключ", не могу.
Пример кода подкатом.
+
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, JwaWinCrypt, LazUTF8, JwaWinSta, JwaWinBase, JwaWinType;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.Button1Click(Sender: TObject);
var f: file;
    encCert: PByte;
    encCertLen: DWORD;
    //store: HCERTSTORE;
    context: PCCERT_CONTEXT;
    //n: PPCCERT_CONTEXT;
    encType: DWORD;
    nameBLOB: CERT_NAME_BLOB;
    size: DWORD;
    nameString: PChar;
    s:TStrings;
    FT:JwaWinBase.TFileTime;
begin
   s:=TStringList.Create;
   s.Clear;
   AssignFile(f, 'c:\temp\123.crt');
   reset(f, 1);
   encCertLen := FileSize(f);
   GetMem(encCert, encCertLen);
   BlockRead(f, encCert^, encCertLen);
   CloseFile(f);

   encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
   context := CertCreateCertificateContext(encType, encCert, encCertLen);

   if context = nil then
   begin
   MessageDlg('Error creating certificate context', mtError, [mbOK], 0);
   exit;
   end;

   nameString := StrAlloc(512);

   FT.dwLowDateTime:=context^.pCertInfo^.NotBefore.dwLowDateTime;
   FT.dwHighDateTime:=context^.pCertInfo^.NotBefore.dwHighDateTime;

   s.Add('context^.pCertInfo^.NotBefore: '+DateTimeToStr(FileTime2DateTime(FT)));

   s.Add('==========================');


   FT.dwLowDateTime:=context^.pCertInfo^.NotAfter.dwLowDateTime;
   FT.dwHighDateTime:=context^.pCertInfo^.NotAfter.dwHighDateTime;

   s.Add('context^.pCertInfo^.NotAfter: '+DateTimeToStr(FileTime2DateTime(FT)));

   s.Add('==========================');



   s.Add('context^.pCertInfo^.Subject');
   nameBLOB := context^.pCertInfo^.Subject;
   size := CertNameToStr(encType, @nameBlob, CERT_X500_NAME_STR,nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');

   s.Add('==========================');

   s.Add('context^.pCertInfo^.Issuer');
   nameBLOB := context^.pCertInfo^.Issuer;
   size := CertNameToStr(encType, @nameBlob, CERT_X500_NAME_STR, nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');

   s.Add('==========================');

   //context^.hCertStore;

   {nameBLOB := context^.pCertInfo^.rgExtension;
   size := CertNameToStr(encType, @nameBlob, CERT_SIMPLE_NAME_STR,nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');}

   //ShowMessage(s.Text);
   Memo1.Lines.Text:=s.Text;
   FreeMem(encCert, encCertLen);
   FreeAndNil(s);
end;

end.


Кто может подсказать, в какую сторону копать.
Ответ:
sql2012
Когда CertGetEnhancedKeyUsage вернет false, будешь к Usage=nil обращаться и получишь AV...

Я это прекрасно вижу, это фактически копи-паст, с некоторыми изменениями.
Вопрос: CryptoAPI

Добрый день, делаю инициализацию для работы с CryptoApi вот так:

Код:

type
  HCRYPTPROV  = ULONG;
  PHCRYPTPROV = ^HCRYPTPROV;
  HCRYPTKEY   = ULONG;
  PHCRYPTKEY  = ^HCRYPTKEY;
  HCRYPTHASH  = ULONG;
  PHCRYPTHASH = ^HCRYPTHASH;

var
 BaseCryptProv:HCRYPTPROV;
 BaseCryptKey:HCRYPTKEY;
 MyID:String[255];

Function InitializationCryptBase:Boolean;
var
 Hash:HCRYPTHASH;
 L:Integer;
begin
Result:=False;
try
if CryptAcquireContext(@BaseCryptProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then
   begin 
   if CryptCreateHash(BaseCryptProv, CALG_SHA, 0, 0, @Hash) then
      begin                        
      if CryptHashData(Hash, @MyID[1], length(MyID), 0) then
         begin   
         if CryptDeriveKey(BaseCryptProv, CALG_RC4, hash, 0, @BaseCryptKey) then
            begin 
            Result:=True;
            end;
         CryptDestroyHash(Hash);
         end;
      end;
   end;
L:=GetLastError;
WriteErrorReportStr('Error Last - '+IntToStr(L));
except
end;
end;

Пишу все чудо на XE5 все отлично от работы юзерского акуанта. но если запустить файл из под системы (LOCAL SERVICE в виде сервиса) то происходит ощибка на вызове CryptCreateHash с номером 87.
Ответ: в WCrypt32.pas корявые декларации функций CryptoApi без учета 64-битности.

HCRYPTKEY = ULONG; // BAD DECLARATION !!!!
ULONG = CARDINAL. // ALWAYS 32-BIT VARIABLE !!!

Если глянуть в msdn to HCRYPTKEY это Handle, то есть тип THandle.

HCRYPTKEY = THANDLE; // GOOD PASCAL DECLARATION
THandle = NativeUInt;

Поменяйте у себя корректно типы в WCrypt32 и все будет работать в Win64 среде вызовов как положено.
Это кстати касается и
HCRYPTPROV = ULONG;
HCRYPTHASH = ULONG;
Вопрос: CryptoAPI + RSA

Вопрос - Можно ли средствами CryptoAPI зашифровать данные именно RSA, без всяких там симметричных алгоритмов?

:) Спасибо за ответы.
Ответ:

Вопрос: Что такое CryptoApi и как можно его использовать с алгоритмом CALG_3DES?

Добрый день, форумчане.

Стоит задача написать программку для шифрования/дешифрирования с помощью симметричного алгоритма CALG_3DES из CryptoApi на C#.

Данную задачу можно выполнить с использованием
C#
1
using System.Security.Cryptography;
там есть класс
C#
1
TripleDES и TripleDESCryptoServiceProvider
У меня возникает вопрос: что такое CryptoApi?
В интернете нашел файл CryptoApi.cs (в приложении).
Как я понимаю это альтернативная библиотека или ... (что это и как это использовать?)

Буду благодарен любой помощи))
Ответ:
Вопрос: MS CryptoAPI получение контекста публичного ключа из CER файла

Есть сертификат в формате CER защищенный паролем, нужно получить его PCCERT_CONTEXT.
Ответ: Точнее говоря, нужно повторить, используя MS CryptoAPI, следующий код на .Net:

public static void EncryptAesKey(byte[] payload, string encryptionCert, string encryptionCertPassword, string outputFilePath)
{
X509Certificate2 cert = new X509Certificate2(encryptionCert, encryptionCertPassword);

using (RSACryptoServiceProvider rsa = cert.PublicKey.Key as RSACryptoServiceProvider)
{
byte[] encryptedKey = rsa.Encrypt(payload, false);
File.WriteAllBytes(outputFilePath, encryptedKey);
}
}
Вопрос: Проверка введенного числа через Console.ReadKey и исключение

Прохожу уроки по C# на канале youtube, там достаточно быстро проходят темы связанные с циклами и операторами if, без особых примеров их использования, в принципе все понятно, но в комментариях люди спрашивают как их использовать, и я решил сделать небольшой пример, на основании того что понял..

Задача консольной игры, выводить варианты из 3х выборов, в данном случае ящиков, в которых находится, в одном 50 очков во втором 100 очков и третий "яд" или 1 в коде.

Классом Random должно перебираться значение переменной которая в свою очередь определяет в каком ящике что лежит..

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


ПРОБЛЕМА: Программа исполняется нормально, доходит до введения числа "console.readkey" при введение любого числа, Visual Studio жутко виснит, выдает окно проблемы, просит выслать отчёты, а в самом коде указать на проблемную точку не может. Скрин ошибки:


Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
 
            Random cointRand = new Random();
 
            int box = 0, box1 = 0, box2 = 0;
            int triger;
            int start;
            int coint = 0;
            int life = 0;
            int score = 0;
            int lvl = 0;
            string a, b, c, d;
            a = "Игра действительно не для слабых, удачи!";
            b = "Вам не хватило везения, и вы выбрали яд, прощайте.";
            c = "Повезло, ящик содержал очки!";
            d = "Уровень № " + lvl;
               
            // Вступительная речь
            Console.WriteLine("Давай поиграем!");
            Console.WriteLine("Ты должен выбрать один из 3х ящиков, в одном из них яд!");
            Console.WriteLine("В двух других очки, набери как можно больше очков.");
            Console.WriteLine("Ты готов?! yes = 1 \\ no = 2 ");
 
            // Проверка согласия игрока на игру
             start = Convert.ToInt32(Console.ReadLine());
             if (start == 1)
                 Console.WriteLine("Храбрец, угадывай.");
             else if (start == 2)
             {
                 life = 2;
                 Console.WriteLine(a);
             }
             
 
               // Перебор вариантов зависящий от числа выданного Рандомизатором содержания ящиков. 
 
            if (coint == 0){
                        box = 1;
                        box1 = 50;
                        box2 = 100;
            }
            else if (coint == 1)
            {
                box = 50;
                box1 = 1;
                box2 = 100;
            }
            else if (coint == 2)
            {
                box = 100;
                box1 = 50;
                box2 = 1;
            }
 
            // Цикл предоставления выбора ящиков, с обновлением рандомного числа, и перезаписью содержания переменной score
            do {
                
                coint = cointRand.Next(0, 2);   // Рандомизируем содержание боксов
                if (life != 2)                  // проверяем не отказался ли игрок от игры, если нет начинаем игру
                {
                    Console.WriteLine(d + lvl++);          // Вывод на экран переменной d и номер уровня
                    Console.WriteLine("Набраные очки = " + score);   // Вывод на экран текста + переменной score
                    Console.WriteLine("Ящик 1, Ящик 2, Ящик 3");
                   [COLOR="Red"] triger = Convert.ToInt32(Console.ReadKey());      [/COLOR]  // Запрашиваем число от 1 до 3 с последующей записью числа в переменную triger
                }
           
 
                // Варианты выбора разных чисел, при разных значениях переменной coint и последствия такого выбора.
                     // Вариант №1
                if (triger == 1 && coint == 0)
                {
                    life = 2;
                    Console.WriteLine(b);
                } 
                
                else if (triger == 2 && coint == 0){
                    Console.WriteLine(c);
                    score = score + box1; 
 
                }   else if(triger == 3 && coint == 0){
                    Console.WriteLine(c);
                    score = score + box2; 
                }
 
                      // Вариант №2
                else if (triger == 2 && coint == 1)
                {
                    life = 2;
                    Console.WriteLine(b);
 
                }
                else if (triger == 1 && coint == 1)
                {
                    Console.WriteLine(c);
                    score = score + box;
 
                }
                else if (triger == 3 && coint == 1)
                {
                    Console.WriteLine(c);
                    score = score + box2;
                }
                          // Вариант №3
                else if (triger == 1 && coint == 2)
                {
                    Console.WriteLine(c);
                    score = score + box;
 
                }
                else if (triger == 2 && coint == 2)
                {
                    Console.WriteLine(c);
                    score = score + box1;
 
                }
                else if (triger == 3 && coint == 2)
                {
                    Console.WriteLine(c);
                    score = score + box2;
                }
 
 
 
            } while (life == 1);    // Проверка жизни игрока, и повтор цикла
            
 
 
 
 
            Console.ReadKey();
        }
    }
}


Добавлено через 7 минут
Ещё один вид ошибки:


Добавлено через 8 минут
И ещё один скрин
Ответ:
Сообщение от PiloD
Вывел переменную на экран, что бы проверять значения и увидел там при вводе 1 цифру 49 при вводе 2 цифру 50 и 3 цифру 51..
Все правильно. посмотрите таблицу ascii. Каждый символ имеет свой код.
Поэтому пишем .ToString()
C#
1
Console.WriteLine(key.KeyChar.ToString());
Добавлено через 4 минуты
Сообщение от PiloD
Тут точно такой же метод приёма и конвертации входящего значения в переменную Int, и программа принимает его и срабатывает как надо, а в случае такой же схемы но уже внутри цикла, оно не работало! Это как-то связанно с тем что попытка конвертации происходила в цикле а проверка конвертации "согласия на игру" проходила вне цикла?
Выполняйте программу по шагам. Смотрите значения переменных. Делаете вывод.
Вопрос: Как сделать универсальные проверки XML в .Net?

Всем привет! Разрабатываю веб сервис(.net), который основан на получения и отправки xml. Проблема в том, что для каждого xml который загружается выполняются определенные проверки и их очень много и они часто меняются. Хотелось эти проверки хранить в определенной структуре( в БД или еще как - нибудь , возможно даже и БЗ) и изменять их действие через клиента и конечно выполнять.Пример xml(на самом деле xml очень большие до 6000 строк)
Код XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<list_actions>
<type>1</type>
<main_date_begin>2015-01-01</main_date_begin>
<main_date_end>2015-01-05</main_date_end>
<main_summ>15000</main_summ>
<action>
   <name>Добавлен новых данных </name>
   <type>14</type>
   <date_begin>2015-01-01</date_begin>
   <date_end>2015-01-02</date_end>
   <summ_action>3000</summ_action>
</action>
<action>
   <name>Оформление отчетов</name>
   <type>14</type>
   <date_begin>2015-01-01</date_begin>
   <date_end>2015-01-03</date_end>
   <summ_action>4000</summ_action>
</action>
</list_actions>
Пример проверок:
1)main_summ равна сумме всех <summ_action>,
2)main_date_begin =< main_date_end
3)main_date_begin =< всех date_end
4)type существует в определенном справочнике и т.д
Подскажите возможно ли и как подобные поверки хранить в БД и их использовать, либо другим образом для того что бы их редактирования через клиента? Где их проверять на сервере или в БД(PostgreSQL)?
Ответ: Flinch, можно. Конкретная реализация зависит от того кто будет редактировать эти правила. Для программистов можно сделать решение с помошью C#, динамической компиляции и исполнения. Для обычных пользователей можно сделать свой язык и/или графический конструктор проверок. Выполнять проверки будем в сервисе т.к. врядли возможности БД это позволят. Также можно посмотреть на решения типа Microsoft BizTalk Server.
Вопрос: SSL:Удаленный сертификат недействителен согласно результатам проверки подлинности.

А реально кодом побороть эту ошибку?

    Private pop3Stream As Stream
...
         If m_useSSL Then
          'get SSL stream
          Try
            CallTrace("   Get SSL connection")
            pop3Stream = New SslStream(serverTcpConnection.GetStream(), False)
            pop3Stream.ReadTimeout = m_readTimeout
          Catch ex As Exception
            Throw New Pop3Exception("Server " + m_popServer + " found, but cannot get SSL data stream." & vbLf & "Runtime Error: " + ex.ToString())
          End Try

          'perform SSL authentication
          Try
            CallTrace("   Get SSL authentication")
            DirectCast(pop3Stream, SslStream).AuthenticateAsClient(m_popServer)
          Catch ex As Exception
            Throw New Pop3Exception("Server " + m_popServer + " found, but problem with SSL Authentication." & vbLf & "Runtime Error: " + ex.ToString())
          End Try
        Else


Run Time Error Occured:
Server bla-bla-bla.com found, but problem with SSL Authentication.
Runtime Error: System.Security.Authentication.AuthenticationException: Удаленный сертификат недействителен согласно результатам проверки подлинности.
   в System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
...


Возникает например на агаве при любом коннекте по SSL(POP3, IMAP),
на форумах здесь тема эта в бытовом смысле поднималась

В почтовом клиенте типа OE чтобы обойти "принят недостоверный сертификат" надо нажать кнопку "Продолжить", часто один раз на всю дальнейшую жизнь.

Нашел вот еще:

Ошибка при проверке SSL-сертификата
Чтобы воспроизвести ошибку при проверке SSL-сертификата, когда WinHTTP не предоставляется конфигурация прокси-сервера, выполните указанные ниже действия.
1. Установите приложение, которое подключается к веб-службе по протоколу SSL. Запустите приложение с учетной записью Network Service или Local System.
Укажите в файле app.config приложения, что подключение осуществляется через прокси-сервер.
2. Приложение выдаст следующее исключение:
WebException: System.Net.WebException: Ошибка подключения к веб-службе: Базовое соединение закрыто:
 Не удалось установить доверительные отношения для защищенного канала SSL/TLS.
 ---> System.Net.WebException: Базовое соединение закрыто: Не удалось установить доверительные отношения для защищенного канала SSL/TLS.
 ---> System.Security.Authentication.AuthenticationException: Удаленный сертификат недействителен согласно результатам проверки подлинности.

Это происходит потому, что приложение предоставляет платформе .NET сведения о конфигурации прокси-сервера в файле app.config, а WinHTTP этих сведений не получает. Это приводит к сбою запросов AIA и промежуточных центров сертификации в процессе проверки допустимости цепочки сертификатов.

Чтобы устранить эту проблему, настройте прокси-сервер WinHTTP в соответствии с конфигурации в файле app.config приложения с помощью программы proxycfg.exe или функции WinHttpSetDefaultProxyConfiguration.


Меня интересует, можно ли это обойти кодом (желательно безусловно без msgbox-ов и без подстроек чего-то там в системе какими-то утилитами).
Чтоб процесс автоматом пошел дальше (ну запись в логе, пожалуйста).
Ответ: buser,

Ну вот такой код накатал без деталей :
В Form1_Load на WinHttpConnect Callback ловится (сессия hSession)
А в ButtonConnect_Click - НЕ ловится сколько не жми (чужая сессия hSession_l), если заменить на hSession то понятно ловится.
На CDO и даже на Net.Mail - не ловит.
Т.е. эта штука только на свою сессию ставится,
а мне надо на чужую, типа глобальный хак.

  Public Const WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0
  Public Const WINHTTP_NO_PROXY_NAME = 0
  Public Const WINHTTP_NO_PROXY_BYPASS = 0

  Public Declare Function WinHttpCloseHandle Lib "winhttp.dll" _
   (ByVal hInternet As IntPtr) As Boolean
  Public Declare Function WinHttpOpen Lib "winhttp.dll" _
   (ByVal pwszUserAgent As String, ByVal dwAccessType As Integer, ByVal pwszProxyName As String, _
   ByVal pwszProxyBypass As String, ByVal dwFlags As Integer) As IntPtr

  Public Delegate Sub WINHTTP_STATUS_CALLBACK_Delegate(ByVal hInternet As IntPtr, _
    ByVal dwContext As IntPtr, ByVal dwInternetStatus As IntPtr, _
    ByVal lpvStatusInformation As IntPtr, ByVal dwStatusInformationLength As Integer)

  Public Const WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS As UInteger = &HFFFFFFFFUI

  Public Declare Function WinHttpSetStatusCallback Lib "winhttp.dll" _
   (ByVal hInternet As IntPtr, ByVal lpfnInternetCallback As WINHTTP_STATUS_CALLBACK_Delegate, _
   ByVal dwNotificationFlags As UInteger, ByVal dwReserved As IntPtr) As WINHTTP_STATUS_CALLBACK_Delegate

  Public Declare Function WinHttpConnect Lib "winhttp.dll" _
   (ByVal hSession As IntPtr, ByVal pswzServerName As String, ByVal nServerPort As Integer, _
   ByVal dwReserved As Integer) As IntPtr

  Dim hSession As IntPtr

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    hSession = WinHttpOpen("A WinHTTP Example Program/1.0",
                                    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                    WINHTTP_NO_PROXY_NAME,
                                    WINHTTP_NO_PROXY_BYPASS, 0)
    If (hSession) Then
      ' Install the status callback function.
      WinHttpSetStatusCallback(hSession, _
       AddressOf WINHTTP_STATUS_CALLBACK, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, IntPtr.Zero)

      'Place additional code here.
      WinHttpConnect(hSession, "server.com", 993, 0)

      ''When finished, release the HINTERNET handle.
      'WinHttpCloseHandle(hSession)
    Else
      Debug.Print("Error in WinHttpOpen.")
    End If

  End Sub

  Private Sub ButtonConnect_Click(sender As Object, e As EventArgs) Handles ButtonConnect.Click
    Dim hSession_l As IntPtr = WinHttpOpen("A WinHTTP Example Program/1.0",
                                    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                    WINHTTP_NO_PROXY_NAME,
                                    WINHTTP_NO_PROXY_BYPASS, 0)
    WinHttpConnect(hSession_l, "server.com", 993, 0)

  End Sub

  Public Sub WINHTTP_STATUS_CALLBACK(ByVal hInternet As IntPtr, _
    ByVal dwContext As IntPtr, ByVal dwInternetStatus As IntPtr, _
    ByVal lpvStatusInformation As IntPtr, ByVal dwStatusInformationLength As Integer)
    Debug.Print("WINHTTP_STATUS_CALLBACK")
  End Sub

buser
.. может проще закачать сертификат и в трасты добавить?

я думаю, программой добавлять за пользователя сертификаты в хранилище, да еще невалидные - это уже перебор,
хватит того итак уже научил молча обходить "защиту" (в 3-х из 4-х случаев успешно: POP3, IMAP и Net.Mail).

Можно конечно вместо CDO-шного .Send тупо получить .eml как стринг (из CDO) и написать еще один класс для SMTP (как сделал для POP3/IMAP, думаю там команды еще проще) и тогда все в моих руках, но кажется итак уже увлекся.
Вопрос: Делаем регистрацию для своей программы

Доброе время суток!!
Наверняка, если ты напишешь супер программу ты захочешь на ней бабло заработать. Вот только может хрень такая получиться, ты продашь челу программу, а он начнет ее распространять(сайты всякие делать, на болванки скидывать(и продавать)). Так чтоб этого избежать, т.е. защитить свою программу от пиратов и злых дядек, надо сделать регистрацию программы. Т.е. программой сможет пользоваться только тот кто заплатил за нее деньги, и зарегистрировал. Надо сделать так, что б на каждом компе был свой серийный номер и ключ, т.к. если у всех будут одинаковые ключи и с/н то ты продашь ее одному челу, а он начнет всем говорить коды.

Ну, тянуть не буду, скажу идею:

На форме 2 текст. поля, первое текст. поле это с/н, при первом запуске программы в заныканый файл(или реестр) записывается случайный с/н(RND). Второе текстовое поле, это ключ. Он высчитывается в зависимости от с/н, по определенной формуле(например ключ = с/н * 3/555+1). Так вот, чел присылает тебе свой с/н(а он на каждом компе свой) + бабло, а ты ему ключ. Идею понял?? Ну тогда начнем`с:
Как я уже и говорил, на форму кинь кнопку(Caption = "Регистрация"), 2 текст. поля(в ряд), 2 метки(у первой Caption = "Серийный номер", она находится напротив первого текст. поля, у второй: Caption = "Ключ", напротив второго текст. поля). Вот что у тебя должно получиться:
собственно интересует следующие вопросы:
1) у кого какие идеи (если можно поделитесь кодом)
2) вот нашел такой код правда на vb 6 помогите под vb2010 переделать не соображу плиз
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Dim SNPath As String ' В этой переменной будет храниться путь к заныканому файлу с с/н
Dim GetReestr As String ' В эту переменную будет читаться данные из реестра
Dim Serial As String ' А эта переменная, будет загружать в текст. поле 1 с/н из файла
 
Function Start() ' Эта функция будет выполняться если программа зарегистрирована
End ' Я написал End, а ты можешь сюда что - нбудь по умнее вставить
End Function
 
Private Sub Form_Load() Randomize ' Этот оператор нужен для того, чтоб всегда генерировались случайные числа(RND(ты что забыл??))
On Error Resume Next ' Если происходит ошибка, то игнорируем ее
GetReestr = GetSetting("proga", "serial", "serial") ' Читаем из реестра значение параметра serial(если serial = 0, значит программа не зарегистрированая, а если 1 то зарег-на)
 
SNPath = Environ("windir") & "key.sn" ' В переменную SNPath - записываем путь к заныканому в папке windows файлу key.sn
f = FreeFile
 
If Val(GetReestr) <> 1 Then ' Если GetReestr не равен 1, то продолжаем регистрацию, если же = 1, то программа уже зарегистрирована
If Dir(SNPath) = "" Then ' Если файла с с/н не существует, то:
Text1.Text = Fix(Rnd * 8000000000#) ' Генерируем случайное число(в любом пределе, можно вместо 8 с деветью нулями написать любое число), и округляем его(Fix())
Serial = Text1.Text ' Это число записываем в перем. Serial
Open SNPath For Output As f ' Открываем заныканный файл
Print #f, Text1.Text ' Записываем в него с/н из текст. поля 1
Close #f ' Закрываем
SaveSetting "proga", "serial", "serial", 0 ' Записываем в реестр параметр Serial со значением 0(ноль означает что программа не зарегистрирована)
Else ' Если же файл существует, то читаем из него с/н
Open (SNPath) For Input As f
Serial = Val(Input(LOF(f), f))
Text1.Text = Serial ' В текс. поле помещаем с/н
Close #f
End If
Else ' Если же в реестре параметр Serial = 1(программа зарег-на), то запускаем функцию Start
Start
End If
End Sub
 
Private Sub Command1_Click() ' При нажатии на кнопку:
Text1.Text = Serial ' Копируем в текст. поле значение переменной serial(на случай, если чел изменил текст в текст. поле 1)
If Text2.Text = Fix(Val(Serial) * 3 + 333 / 2) Then ' Вот самое интересное :-), если текст. поле 2(ключ) равен с/н умноженному на 3 + 333 / 2
SaveSetting "proga", "serial", "serial", 1 
MsgBox "Программа зарегистрирована" 
Start ' Запускаем функцию Start
Else
MsgBox "Введен не правильный ключ!!! Для регистрации отправь автору программы с/н и $, а он вышлет тебе ключ" End If
End Sub
если нужен вам пример keygen выложу
вот код дя Keygen: соотведственно 2 texbox и кнопку
Visual Basic
1
2
3
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        TextBox2.Text = Fix(Val(TextBox1.Text) * 3 + 333 / 2) ' По С/Н узнаем ключ 
    End Sub
Ответ: Или декомпилируешь программу, выпиливаешь проверку и компилируешь обратно. Это же .Net. Поэтому простые методы, как у Faraon, бесполезны.

Или, техподдержка закрылась вместе с компанией-разработчиком. Тогда и долбить некого, только своей головой об стену. Так как законно приобретённое более не работает, техпроцессы стоят, а спросить не с кого.