-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrsa_digital_signature.cpp
148 lines (117 loc) · 4.33 KB
/
rsa_digital_signature.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
#include <iostream>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include "rsa_digital_signature.hpp"
#include "utils.hpp"
using namespace std;
void RSADigitalSignature::RunRSADigitalSignature(int keysize) {
unsigned char input[] = "This is the message.";
size_t input_len = sizeof(input);
unsigned char message_digest[EVP_MAX_MD_SIZE];
unsigned int digest_len = 0;
//key generation
EVP_PKEY* rsa_keypair = GenerateRSAKeys(keysize);
//get the hash digest.
DigestMessage(input, input_len, message_digest, &digest_len);
cout << "\nPrinting hash digest :\n";
PrintCipherText(message_digest, digest_len);
size_t signature_len = EVP_PKEY_size(rsa_keypair);
unsigned char* signature = new unsigned char[signature_len];
// Sign the digest
SignDigest(rsa_keypair, message_digest, digest_len, signature, &signature_len);
// Verify the signature
VerifySignature(rsa_keypair, message_digest, digest_len, signature, signature_len);
EVP_PKEY_free(rsa_keypair);
delete[] signature;
}
EVP_PKEY* RSADigitalSignature::GenerateRSAKeys(int keysize) {
int keysize_in_bits = keysize * 8;
EVP_PKEY* rsa_keypair = NULL;
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
if (ctx == NULL)
{
cout << "error in ctx.\n";
return NULL;
}
if (EVP_PKEY_keygen_init(ctx) <= 0)
{
cout << "error in init of keygen.\n";
EVP_PKEY_CTX_free(ctx);
return NULL;
}
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, keysize_in_bits) <= 0)
{
cout << "error in setting key param.\n";
EVP_PKEY_CTX_free(ctx);
return NULL;
}
if (EVP_PKEY_keygen(ctx, &rsa_keypair) <= 0)
{
cout << "error in generating key.\n";
EVP_PKEY_CTX_free(ctx);
return NULL;
}
EVP_PKEY_CTX_free(ctx);
return rsa_keypair;
}
void RSADigitalSignature::DigestMessage(const unsigned char *input_message, size_t input_len, unsigned char *message_digest, unsigned int *digest_len) {
EVP_MD_CTX *message_digest_ctx = EVP_MD_CTX_new();
if(message_digest_ctx == NULL) {
cout << "Can't create a new ctx.\n";
return;
}
if(EVP_DigestInit(message_digest_ctx, EVP_sha256()) != 1) {
cout << "can't initialize a message digest.\n";
EVP_MD_CTX_free(message_digest_ctx);
return;
}
if(EVP_DigestUpdate(message_digest_ctx, input_message, input_len) != 1) {
cout << "Can't update the hash value in ctx.\n";
EVP_MD_CTX_free(message_digest_ctx);
return;
}
if(EVP_DigestFinal(message_digest_ctx, message_digest, digest_len) != 1) {
cout << "Can't get the digest value into message_digest.\n";
EVP_MD_CTX_free(message_digest_ctx);
return;
}
EVP_MD_CTX_free(message_digest_ctx);
}
void RSADigitalSignature::SignDigest(EVP_PKEY* rsa_keypair, unsigned char* message_digest, size_t digest_len, unsigned char* signature, size_t* signature_len) {
EVP_MD_CTX* signing_ctx = EVP_MD_CTX_new();
if (!signing_ctx) {
cout << "Error creating signing context.\n";
return;
}
if (EVP_DigestSignInit(signing_ctx, NULL, EVP_sha256(), NULL, rsa_keypair) != 1) {
cout << "Error in sign init.\n";
EVP_MD_CTX_free(signing_ctx);
return;
}
if (EVP_DigestSign(signing_ctx, signature, signature_len, message_digest, digest_len) != 1) {
cout << "Error in signing.\n";
EVP_MD_CTX_free(signing_ctx);
return;
}
cout << "Digest signed successful.\n";
EVP_MD_CTX_free(signing_ctx);
}
void RSADigitalSignature::VerifySignature(EVP_PKEY* rsa_keypair, unsigned char* message_digest, size_t digest_len, unsigned char* signature, size_t signature_len) {
EVP_MD_CTX* verify_ctx = EVP_MD_CTX_new();
if (!verify_ctx) {
cout << "Error creating verify context.\n";
return;
}
if (EVP_DigestVerifyInit(verify_ctx, NULL, EVP_sha256(), NULL, rsa_keypair) != 1) {
cout << "Error in verify init.\n";
EVP_MD_CTX_free(verify_ctx);
return;
}
if (EVP_DigestVerify(verify_ctx, signature, signature_len, message_digest, digest_len) != 1) {
cout << "Signature verification failed.\n";
EVP_MD_CTX_free(verify_ctx);
return;
}
cout << "Sign verification success.\n";
EVP_MD_CTX_free(verify_ctx);
}