Я хочу создать простую программу, которая будет шифровать строку с использованием алгоритма RSA, а затем расшифровывать ее (cygwin, windows
)
Вот мой код
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>
#define KEY_LENGTH 2048
#define PUB_EXP 3
#define PRINT_KEYS
#define WRITE_TO_FILE
int main(void) {
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
printf("Generating RSA (%d bits) keypair...", KEY_LENGTH);
fflush(stdout);
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);
return -1;
}
#ifdef WRITE_TO_FILE
// Write the encrypted message to a file
FILE *out = fopen("out.bin", "w");
fwrite(encrypt, sizeof(*encrypt), RSA_size(keypair), out);
fclose(out);
printf("Encrypted message written to file.\n");
free(encrypt);
encrypt = NULL;
// Read it back
printf("Reading back encrypted message and attempting decryption...\n");
encrypt = (char *)malloc(RSA_size(keypair));
out = fopen("out.bin", "r");
fread(encrypt, sizeof(*encrypt), RSA_size(keypair), out);
fclose(out);
#endif
// 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);
return -1;
}
printf("Decrypted message: %s\n", decrypt);
RSA_free(keypair);
BIO_free_all(pub);
BIO_free_all(pri);
free(pri_key);
free(pub_key);
free(encrypt);
free(decrypt);
free(err);
return 0;
}
У меня проблема в том, чтово время компиляции с помощью команды
$ gcc -I /usr/include/ -L /usr/lib/ ip.cpp -o ip.exe -lcrypto
.
Вот ошибки, которые у меня есть:
In file included from /usr/include/errno.h:9:0,
from /usr/include/openssl/err.h:140,
from ip.cpp:9:
/usr/include/sys/errno.h:14:0: warning: "errno" redefined
#define errno (*__errno())
^
In file included from /usr/lib/gcc/x86_64-w64-mingw32/4.9.2/include/stddef.h:1:0,
from /usr/include/sys/cdefs.h:45,
from /usr/include/time.h:11,
from /usr/include/openssl/asn1.h:62,
from /usr/include/openssl/rsa.h:62,
from ip.cpp:7:
/usr/x86_64-w64-mingw32/sys-root/mingw/include/stddef.h:19:0: note: this is the location of the previous definition
#define errno (*_errno())
^
In file included from /usr/include/sys/select.h:26:0,
from /usr/include/sys/types.h:85,
from /usr/include/time.h:28,
from /usr/include/openssl/asn1.h:62,
from /usr/include/openssl/rsa.h:62,
from ip.cpp:7:
/usr/include/sys/_timeval.h:40:18: error: conflicting declaration ‘typedef long int time_t’
typedef _TIME_T_ time_t;
^
In file included from /usr/x86_64-w64-mingw32/sys-root/mingw/include/stddef.h:7:0,
from /usr/lib/gcc/x86_64-w64-mingw32/4.9.2/include/stddef.h:1,
from /usr/include/sys/cdefs.h:45,
from /usr/include/time.h:11,
from /usr/include/openssl/asn1.h:62,
from /usr/include/openssl/rsa.h:62,
from ip.cpp:7:
/usr/x86_64-w64-mingw32/sys-root/mingw/include/crtdefs.h:138:20: note: previous declaration as ‘typedef __time64_t time_t’
typedef __time64_t time_t;
Как вы видите, первая ошибка заключается в том, что errno
определено Gotsдважды.Я проверил и в errno.h
есть этот код:
#ifndef _REENT_ONLY
#define errno (*__errno())
Определение _REENT_ONLY
исправляет эту ошибку, но затем в stdio.h
есть это:
#ifndef _REENT_ONLY
FILE * _EXFUN(fopen, (const char *__restrict _name, const char *__restrict _type));
, так что тогдаУ меня fopen undefined error
.Кроме того, я не думаю, что определение некоторых значений без реального знания того, для чего они нужны, является плохой идеей.
Затем я попытался вручную закомментировать строки, в которых данные были определены во второй раз, чтобы просто построить их успешно и проверитьпрограмма, но потом я получил:
/tmp/ccC3voSz.o:ip.cpp:(.rdata$.refptr._impure_ptr[.refptr._impure_ptr]+0x0): undefined reference to `_impure_ptr'
Итак, в конце у меня две проблемы (может быть, они даже как-то связаны):
Как избавиться от конфликтов объявлений?
Как исправить undefined reference to _impure_ptr