-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathencryptrsa.cpp
177 lines (139 loc) · 4.08 KB
/
encryptrsa.cpp
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
/*
Taneli Leppanen
BIE-BEZ Security
*/
#include <string>
#include <fstream>
#include <iostream>
#include "openssl/evp.h"
#include "openssl/pem.h"
using namespace std;
void rsa_encrypt(const char * pubkeyFileName, string inFileName, const char *cipherName) {
//Loading public key to memory
EVP_PKEY * pubkey;
FILE * pubkeyFile;
pubkeyFile = fopen(pubkeyFileName, "r");
if (pubkeyFile == NULL) {
cout << "Error opening file \"" << pubkeyFileName << "\"" << endl;
cin.get();
exit(EXIT_FAILURE);
}
pubkey = PEM_read_PUBKEY(pubkeyFile, NULL, NULL, NULL);
fclose(pubkeyFile);
if (pubkey == NULL) {
cout << "Erro reading the public key" << endl;
cin.get();
exit(EXIT_FAILURE);
}
// Initialization of variables
unsigned char inBuffer[1024]; // Input buffer
unsigned char outBuffer[1024 + EVP_MAX_BLOCK_LENGTH]; // Output buffer
unsigned char * my_ek = (unsigned char *)malloc(EVP_PKEY_size(pubkey)); // allocate space for encrypted symmet. key
int my_eklen; // enc. sym. key length
unsigned char iv[EVP_MAX_IV_LENGTH]; // IV vector buffer
const EVP_CIPHER * type;
int res;
int outLength;
int length;
//Loading the ciphers
OpenSSL_add_all_ciphers();
EVP_CIPHER_CTX *ctx; // context structure
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL) {
cout << "Context initialization failure" << endl;
cin.get();
exit(EXIT_FAILURE);
}
// Getting the cipher by name and checking if it was found
type = EVP_get_cipherbyname(cipherName);
if (!type) {
printf("Cipher %s not found.\n", cipherName);
cin.get();
exit(EXIT_FAILURE);
}
// Seal initializaion and checking for failure
res = EVP_SealInit(ctx, type, &my_ek, &my_eklen, iv, &pubkey, 1);
if (res == 0) {
cout << "Seal Initialization failure" << endl;
cin.get();
exit(EXIT_FAILURE);
}
// Opening the input file
ifstream fin;
fin.open(inFileName, ios::binary);
if (!fin) {
cout << "Error opening file \"" << inFileName << "\"" << endl;
cin.get();
exit(EXIT_FAILURE);
}
// Parsing the output file name and opening the output file
string outFileName;
outFileName = inFileName.substr(0, inFileName.length() - 4) + "_seal.txt";
ofstream fout;
fout.open(outFileName, ofstream::out | ofstream::trunc | ofstream::binary);
if (!fout) {
cout << "Error opening file \"" << outFileName << "\"" << endl;
fin.close();
cin.get();
exit(EXIT_FAILURE);
}
/*
Write: type, my_ek, my_eklen, iv to the output file
Header structure
Bytes Data
4 L1 = length of cipherName
L1 cipherName
4 my_eklen
my_eklen my_ek
4 L2 = length of iv
L2 iv
*/
// Writing type and its length
length = strlen(cipherName);
fout.write(reinterpret_cast<const char *>(&length), 4);
fout.write((char *)cipherName, length);
// Write my_eklen to output file
fout.write(reinterpret_cast<const char *>(&my_eklen), 4);
// Write my_ek to output file
fout.write((char *)&my_ek[0], my_eklen);
// Writing iv and its length
length = sizeof(iv);
fout.write(reinterpret_cast<const char *>(&length), 4);
fout.write((char *)iv, sizeof(iv));
// Raeding from input file, encrypting it and writing to output file
while (true) {
fin.read((char *)inBuffer, sizeof(inBuffer));
streamsize inLength = fin.gcount();
// EOF reached
if (inLength == 0) {
break;
}
res = EVP_SealUpdate(ctx, outBuffer, &outLength, inBuffer, inLength);
if (res != 1) {
cout << "Seal update failure" << endl;
fout.close();
fin.close();
cin.get();
exit(EXIT_FAILURE);
}
// Write outBuffer to target file
fout.write((const char*)&outBuffer[0], outLength);
}
// Seal finalization
res = EVP_SealFinal(ctx, outBuffer, &outLength);
if (res != 1) {
cout << "Seal finalization error" << endl;
fout.close();
fin.close();
exit(EXIT_FAILURE);
}
// Final write
fout.write((const char*)&outBuffer[0], outLength);
// Clean up
EVP_CIPHER_CTX_free(ctx);
fout.close();
fin.close();
cout << "Sealing complete" << endl;
return;
}