📜 ⬆️ ⬇️

Using the OpenSSL Library in C ++ Projects

image

In my first topic, I will try to explain in detail how to start using the OpenSSL library. Just want to note that the article is aimed at beginners, and since I myself am one of them, the source code was executed without checks and does not claim to be the best. All actions were performed under Windows with the Visual Studio 2013 development environment.

Step 1. Install the necessary components and compile the library


In order to make OpenSSL library friends with Visual Studio, we need:


After downloading the files, install Perl, unpack the openssl-1.0.1a.tar.gz archive and copy its contents to the C: \ openssl folder. Then we open the Perl command line (command line) on behalf of the administrator and write the following commands:
')
cd c:\openssl perl Configure VC-WIN32 --prefix=c:\Temp\openssl ms\do_ms 

Note that after the second command is executed, the last line in the console should be Configured for VC-WIN32 . Configuration completed, now proceed to compile. We find in the start-up in the Visual Studio directory “Developer Command Line”, run as administrator and enter the commands:

 cd c:\openssl nmake -f ms\ntdll.mak nmake -f ms\ntdll.mak install 

This is the end of the compilation. Two ssleay32.dll and libeay32.dll libraries appeared in the C: \ Temp \ openssl \ bin folder , and ssleay32.lib and libeay32.lib appeared in the C: \ Temp \ openssl \ lib folder.

Step 2. Connecting libraries and fixing errors in the development environment


To use the functions of the library, we need to connect header files to the project, but first they need to be placed in the folder where Visual Studio is installed. To do this, go to the directory .. \ Visual Studio \ VC \ include and copy the folder C: \ Temp \ openssl \ include \ openssl there .

Now you can easily connect the header files (for example, rsa):

 #include <openssl/rsa.h> //  RSA #include <openssl/pem.h> //      

You also need to add to the project files with the extension .lib , which we received earlier. To do this, open the Solution Explorer in Visual Studio, find the resource files folder in our project tree, right-click on it -> Add -> Existing element and select our .lib files located in C: \ Temp \ openssl \ lib .

image

It is possible that when you try to build a project, errors like this will appear in the output window:

  "C:\Windows\SysWOW64\srvcli.dll".     PDB-. 

This is treated by allowing characters to download from Microsoft servers. Go to the Tools -> Options tab, select Debug -> Symbols in the tree on the left, put a checkmark next to " Microsoft Symbol Servers " and click OK. Now at the next project compilation the missing files will be loaded automatically.

image
I also recommend to rearrange the configuration of the program assembly in Release , only this way I managed to get rid of some errors.

Step 3. Description of some library functions and sample code


 int RSA_size(const RSA *rsa)   RSA    RSA * RSA_generate_key(int bits, unsigned long e, void(*callback)(int, int, void*), void *cb_arg)       RSA  int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u)      RSA    int PEM_write_RSAPublicKey(FILE *fp, const RSA *x)      RSA    RSA * PEM_read_RSAPublicKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u)         RSA  RSA * PEM_read_RSAPrivateKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u)         RSA  int RSA_public_encrypt(int flen, const unsigned char *from, const unsigned char *to, RSA *rsa, int padding)   "from"         "to" int RSA_private_decrypt(int flen, const unsigned char *from, const unsigned char *to, RSA *rsa, int padding)   "from"         "to".  "-1"    . 

All the necessary components, including the compiled example, can be downloaded from Yandex.Disk .

Sources:


Code example
 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <conio.h> #include <io.h> #include <fcntl.h> #include <stdlib.h> #include <openssl/rsa.h> #include <openssl/pem.h> using namespace std; void GenKeys(char secret[]); void Enc(); void Dec(char secret[]); void GenKeysMenu(); void EncryptMenu(); void DecryptMenu(); void main(){ setlocale(LC_ALL, "Russian"); char key; StartMenu: system("cls"); cout << "--------------  RSA --------------" << endl << endl; cout << " 1.  " << endl; cout << " 2.   " << endl; cout << " 3.   " << endl << endl; cout << " : "; cin >> key; switch (key){ case '1': GenKeysMenu(); goto StartMenu; case '2': EncryptMenu(); goto StartMenu; case '3': DecryptMenu(); goto StartMenu; default: goto StartMenu; } } void GenKeys(char secret[]){ /*       */ RSA * rsa = NULL; unsigned long bits = 1024; /*     */ FILE * privKey_file = NULL, *pubKey_file = NULL; /*    */ const EVP_CIPHER *cipher = NULL; /*  */ privKey_file = fopen("\private.key", "wb"); pubKey_file = fopen("\public.key", "wb"); /*   */ rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL); /*     */ cipher = EVP_get_cipherbyname("bf-ofb"); /*    rsa        . *        */ PEM_write_RSAPrivateKey(privKey_file, rsa, cipher, NULL, 0, NULL, secret); PEM_write_RSAPublicKey(pubKey_file, rsa); /*  ,    rsa */ RSA_free(rsa); fclose(privKey_file); fclose(pubKey_file); cout << "        " << endl; } void Encrypt(){ /*      */ RSA * pubKey = NULL; FILE * pubKey_file = NULL; unsigned char *ctext, *ptext; int inlen, outlen; /*    */ pubKey_file = fopen("\public.key", "rb"); pubKey = PEM_read_RSAPublicKey(pubKey_file, NULL, NULL, NULL); fclose(pubKey_file); /*    */ int key_size = RSA_size(pubKey); ctext = (unsigned char *)malloc(key_size); ptext = (unsigned char *)malloc(key_size); OpenSSL_add_all_algorithms(); int out = _open("rsa.file", O_CREAT | O_TRUNC | O_RDWR, 0600); int in = _open("in.txt", O_RDWR); /*     */ while (1) { inlen = _read(in, ptext, key_size - 11); if (inlen <= 0) break; outlen = RSA_public_encrypt(inlen, ptext, ctext, pubKey, RSA_PKCS1_PADDING); if (outlen != RSA_size(pubKey)) exit(-1); _write(out, ctext, outlen); } cout << "  in.txt       rsa.file" << endl; } void Decrypt(char secret[]){ RSA * privKey = NULL; FILE * privKey_file; unsigned char *ptext, *ctext; int inlen, outlen; /*        */ OpenSSL_add_all_algorithms(); privKey_file = fopen("private.key", "rb"); privKey = PEM_read_RSAPrivateKey(privKey_file, NULL, NULL, secret); /*    */ int key_size = RSA_size(privKey); ptext = (unsigned char *)malloc(key_size); ctext = (unsigned char *)malloc(key_size); int out = _open("out.txt", O_CREAT | O_TRUNC | O_RDWR, 0600); int in = _open("rsa.file", O_RDWR); /*   */ while (1) { inlen = _read(in, ctext, key_size); if (inlen <= 0) break; outlen = RSA_private_decrypt(inlen, ctext, ptext, privKey, RSA_PKCS1_PADDING); if (outlen < 0) exit(0); _write(out, ptext, outlen); } cout << "  rsa.file       out.txt" << endl; } void GenKeysMenu(){ char secret[] = ""; system("cls"); cout << "--------------  RSA --------------" << endl << endl; cout << "     : "; cin >> secret; GenKeys(secret); cout << "      ..."; _getch(); } void EncryptMenu(){ system("cls"); cout << "--------------  RSA --------------" << endl << endl; Encrypt(); cout << "      ..."; _getch(); } void DecryptMenu(){ char secret[] = ""; system("cls"); cout << "--------------  RSA --------------" << endl << endl; cout << "     : "; cin >> secret; Decrypt(secret); cout << "      ..."; _getch(); } 

Source: https://habr.com/ru/post/277935/


All Articles