Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
navira
0 / 0 / 0
Регистрация: 01.07.2015
Сообщений: 1
#1

Как правильно пользоваться openssl RSA_verify? - C++

01.07.2015, 14:31. Просмотров 362. Ответов 0
Метки нет (Все метки)

Приветствую всех на форуме.
Появилась задача подписать короткое сообщение и затем проверять его с помощью публичного ключа.
Пытаюсь разобраться как это все работает.

Генерация ключей вроде работает правильно, а вот подписать и проверить не как не выходит exeшник крешится
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <stdio.h>
#include <string.h>
 
#define APPLINK_STDIN   1
#define APPLINK_STDOUT  2
#define APPLINK_STDERR  3
#define APPLINK_FPRINTF 4
#define APPLINK_FGETS   5
#define APPLINK_FREAD   6
#define APPLINK_FWRITE  7
#define APPLINK_FSETMOD 8
#define APPLINK_FEOF    9
#define APPLINK_FCLOSE  10      /* should not be used */
 
#define APPLINK_FOPEN   11      /* solely for completeness */
#define APPLINK_FSEEK   12
#define APPLINK_FTELL   13
#define APPLINK_FFLUSH  14
#define APPLINK_FERROR  15
#define APPLINK_CLEARERR 16
#define APPLINK_FILENO  17      /* to be used with below */
 
#define APPLINK_OPEN    18      /* formally can't be used, as flags can vary */
#define APPLINK_READ    19
#define APPLINK_WRITE   20
#define APPLINK_LSEEK   21
#define APPLINK_CLOSE   22
#define APPLINK_MAX     22      /* always same as last macro */
 
#ifndef APPMACROS_ONLY
# include <stdio.h>
# include <io.h>
# include <fcntl.h>
 
static void *app_stdin(void)
{
    return stdin;
}
 
static void *app_stdout(void)
{
    return stdout;
}
 
static void *app_stderr(void)
{
    return stderr;
}
 
static int app_feof(FILE *fp)
{
    return feof(fp);
}
 
static int app_ferror(FILE *fp)
{
    return ferror(fp);
}
 
static void app_clearerr(FILE *fp)
{
    clearerr(fp);
}
 
static int app_fileno(FILE *fp)
{
    return _fileno(fp);
}
 
static int app_fsetmod(FILE *fp, char mod)
{
    return _setmode(_fileno(fp), mod == 'b' ? _O_BINARY : _O_TEXT);
}
 
#ifdef __cplusplus
extern "C" {
#endif
 
    __declspec(dllexport)
        void **
# if defined(__BORLANDC__)
        /*
        * __stdcall appears to be the only way to get the name
        * decoration right with Borland C. Otherwise it works
        * purely incidentally, as we pass no parameters.
        */
        __stdcall
# else
        __cdecl
# endif
        OPENSSL_Applink(void)
    {
            static int once = 1;
            static void *OPENSSL_ApplinkTable[APPLINK_MAX + 1] =
            { (void *)APPLINK_MAX };
 
            if (once) {
                OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
                OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout;
                OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr;
                OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf;
                OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets;
                OPENSSL_ApplinkTable[APPLINK_FREAD] = fread;
                OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite;
                OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod;
                OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof;
                OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose;
 
                OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen;
                OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek;
                OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell;
                OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush;
                OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror;
                OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr;
                OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno;
 
                OPENSSL_ApplinkTable[APPLINK_OPEN] = _open;
                OPENSSL_ApplinkTable[APPLINK_READ] = _read;
                OPENSSL_ApplinkTable[APPLINK_WRITE] = _write;
                OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek;
                OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close;
 
                once = 0;
            }
 
            return OPENSSL_ApplinkTable;
        }
 
#ifdef __cplusplus
}
#endif
#endif 
 
#define KEY_LENGTH  2048
#define PUB_EXP     3
#define PRINT_KEYS
#define WRITE_TO_FILE
 
int main() {
    size_t pri_len;            // Length of private key
    size_t pub_len;            // Length of public key
    char   *pri_key;           // Private key
    char   *pub_key;           // Public key
    char   msg[KEY_LENGTH / 8];  // Message to encrypt
    char   *encrypt = NULL;    // Encrypted message
    char   *decrypt = NULL;    // Decrypted message
    char   *err;               // Buffer for any error messages
    //Generate key pair
    RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL);
 
    // To get the C-string PEM form:
    BIO *pri = BIO_new(BIO_s_mem());
    BIO *pub = BIO_new(BIO_s_mem());
 
    PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_RSAPublicKey(pub, keypair);
 
    pri_len = BIO_pending(pri);
    pub_len = BIO_pending(pub);
 
    pri_key = (char*)malloc(pri_len + 1);
    pub_key = (char*)malloc(pub_len + 1);
 
    BIO_read(pri, pri_key, pri_len);
    BIO_read(pub, pub_key, pub_len);
 
    pri_key[pri_len] = '\0';
    pub_key[pub_len] = '\0';
 
#ifdef PRINT_KEYS
    printf("\n%s\n%s\n", pri_key, pub_key);
#endif
    printf("done.\n");
 
    // Get the message to encrypt
    printf("Message to encrypt: ");
    fgets(msg, KEY_LENGTH - 1, stdin);
    msg[strlen(msg) - 1] = '\0';
 
    // Encrypt the message
    encrypt = (char*)malloc(RSA_size(keypair));
    int encrypt_len;
    err = (char*)malloc(130);
    if ((encrypt_len = RSA_public_encrypt(strlen(msg) + 1, (unsigned char*)msg, (unsigned char*)encrypt, keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        goto free_stuff;
    }
 
    // Decrypt it
    decrypt = (char*)malloc(encrypt_len);
    if (RSA_private_decrypt(encrypt_len, (unsigned char*)encrypt, (unsigned char*)decrypt, keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error decrypting message: %s\n", err);
        goto free_stuff;
    }
 
    printf("Decrypted message: %s\n", decrypt);
    //int spc_sign(unsigned char *msg, unsigned int mlen, unsigned char *out, unsigned int *outlen, RSA *r)
    //unsigned char ibuf[] = "compute sha1";
    //unsigned char obuf[20];
    //SHA1(ibuf, sizeof(ibuf), obuf);
 
    //printf("SHA1: %s\n", obuf);
 
 
 
    unsigned char hash[20]; 
    if (!SHA1((unsigned char*)msg, sizeof(msg), hash)) return 0;
    unsigned char *signature;
    unsigned int slen;
    signature = (unsigned char*)malloc(RSA_size(keypair));
    RSA_sign(NID_sha1, hash, 20, signature, &slen, keypair);
    printf("signature: %s\n", signature);
    
    
    
    unsigned char hash1[20];
    BN_CTX *c; 
    int ret; 
    if (!(c = BN_CTX_new())) return 0; 
    if (!SHA1((unsigned char*)msg, sizeof(msg), hash1) || !RSA_blinding_on(keypair, c))
    { 
        BN_CTX_free(c); 
        return 0; 
    } 
    ret = RSA_verify(NID_sha1, hash1, 20, signature, slen, keypair);
    RSA_blinding_off(keypair);
    BN_CTX_free(c); 
    
    printf("signature: retunred %s\n", ret);
 
    
 
free_stuff:
    RSA_free(keypair);
    BIO_free_all(pub);
    BIO_free_all(pri);
    free(pri_key);
    free(pub_key);
    free(encrypt);
    free(decrypt);
    free(err);
}


пробовал также такой вариант


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
unsigned char* signature;
    unsigned int slen;
    unsigned int verified;
    char* message = "Hello World";
    RSA *private_key;
    RSA *public_key;
 
    BIO *priv_bio;
    BIO *pub_bio;
 
    ///////////////////////////////////////////////////// 
 
    priv_bio = BIO_new_mem_buf(pri_key, -1);
    if (priv_bio == NULL) {
        ERR_print_errors_fp(stdout);
        return 1;
    }
 
    private_key = PEM_read_bio_RSAPrivateKey(priv_bio, NULL, NULL, NULL);
    if (private_key == NULL) {
        ERR_print_errors_fp(stdout);
    }
 
    signature = (unsigned char*)malloc(RSA_size(private_key));
    if (RSA_sign(NID_sha1, (unsigned char*)msg, strlen(msg),
        signature, &slen, private_key) != 1) {
        ERR_print_errors_fp(stdout);
    }
 
    ////////////////////////////////////////////////// 
 
 
 
    pub_bio = BIO_new_mem_buf(pub_key, sizeof(pub_key));
    if (pub_bio == NULL) {
        ERR_print_errors_fp(stdout);
        printf("eeeeeeeror");
        return 1;
    }
 
    public_key = PEM_read_bio_RSA_PUBKEY(pub_bio, NULL, NULL, NULL);
    if (public_key == NULL) {
        ERR_print_errors_fp(stdout);
    }
    
    verified = RSA_verify(NID_sha1, (unsigned char*)msg,
        strlen(msg), signature, slen, public_key);
 
    ///////////////////////////////////////////////////// 
 
    printf("VERIFIED: %d\n", verified);
В голове каша полная, помогите понять где ошибка.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.07.2015, 14:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как правильно пользоваться openssl RSA_verify? (C++):

SIGINT с OpenSSL - C++
Приветствую всех! Натыкаюсь в программе (обычная однопоточная консолька, делащая несколько запросиков) на SIGINT. Программа использует...

libcUrl с OpenSSL на MinGW - C++
Помогите! Никак не могу разобраться с libcUrl с OpenSSL, просто libcUrl компилю без проблем, и использую, но нужнен https. ...

Как правильно пользоваться поиском по компонентам ->FindComponent - C++ Builder
В гугле в основном выбивает результаты по делфи, а там где есть про это по билдеру то очень непонятно для мне. Можете мне просто объяснить...

TObserver как пользоваться? - C++ Builder
Доброго времени суток. Извиняюсь за дублирование темы, я задавал ее первый раз в ООП и Паттернах. C++ Rad Studio XE3. Нашел...

Как пользоваться Zlib'om - C++ Builder
Скачал 1.2.8 версию с сайта для Delphi провел .pas через билдера, получил .hpp Подключаю: #include &quot;ZLibEx.hpp&quot; #include...

Как пользоваться ToDo List? - C++ Builder
я хочу узнать как использовать в с++ builder такую тему как TODOlist, т.е. как правильно оформлять эти TODO внутри кода, чтобы потом они...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.07.2015, 14:31
Привет! Вот еще темы с ответами:

Ресурсы проекта. Как ими пользоваться? - C++ Builder
Я создал файл 1.html, записал его в папку проекта, создал файл 1.rc и записал туда имя_ресурса тип_ресурса имя_файла: MYHTML HTMLFILE...

Расскажите как пользоваться утилитой IMPLIB - C++ Builder
Вместе с C++ builder поставляется ряд утилит. Одна из них IMPLIB для перекомпилирования dll. Это консольное приложение. В инете нашел...

Как объявить созданную функцию, чтобы ей пользоваться? - C++ Builder
Создал свою функцию, записал в хедере void __fastcall TForm1::test(TObject *Sender) {} прописал в хедере void __fastcall...

как правильно пользоваться - C++
Здравствуйте, нашел интересный код для интересной задачи (Удалить комментарии из файла), но как сделать так,чтобы программа брала input.txt...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru