evp_rsa_encrypt.cpp
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <iostream>
#include <vector>
void handleErrors() {
ERR_print_errors_fp(stderr);
abort();
}
EVP_PKEY* generateRSAKey() {
EVP_PKEY* pkey = EVP_PKEY_new();
RSA* rsa = RSA_generate_key(2048, RSA_F4, nullptr, nullptr);
if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
handleErrors();
}
return pkey;
}
std::vector<unsigned char> rsaEncrypt(EVP_PKEY* pkey, const std::vector<unsigned char>& plaintext) {
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, nullptr);
if (!ctx) handleErrors();
if (EVP_PKEY_encrypt_init(ctx) <= 0) handleErrors();
size_t outlen;
if (EVP_PKEY_encrypt(ctx, nullptr, &outlen, plaintext.data(), plaintext.size()) <= 0) handleErrors();
std::vector<unsigned char> ciphertext(outlen);
if (EVP_PKEY_encrypt(ctx, ciphertext.data(), &outlen, plaintext.data(), plaintext.size()) <= 0) handleErrors();
EVP_PKEY_CTX_free(ctx);
return ciphertext;
}
std::vector<unsigned char> rsaDecrypt(EVP_PKEY* pkey, const std::vector<unsigned char>& ciphertext) {
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, nullptr);
if (!ctx) handleErrors();
if (EVP_PKEY_decrypt_init(ctx) <= 0) handleErrors();
size_t outlen;
if (EVP_PKEY_decrypt(ctx, nullptr, &outlen, ciphertext.data(), ciphertext.size()) <= 0) handleErrors();
std::vector<unsigned char> plaintext(outlen);
if (EVP_PKEY_decrypt(ctx, plaintext.data(), &outlen, ciphertext.data(), ciphertext.size()) <= 0) handleErrors();
EVP_PKEY_CTX_free(ctx);
return plaintext;
}
int main() {
//OpenSSL_add_all_algorithms();
//ERR_load_crypto_strings();
EVP_PKEY* pkey = generateRSAKey();
std::string message = "Hello, RSA!";
std::vector<unsigned char> plaintext(message.begin(), message.end());
std::vector<unsigned char> ciphertext = rsaEncrypt(pkey, plaintext);
std::vector<unsigned char> decryptedtext = rsaDecrypt(pkey, ciphertext);
std::string decryptedMessage(decryptedtext.begin(), decryptedtext.end());
std::cout << "Decrypted message: " << decryptedMessage << std::endl;
EVP_PKEY_free(pkey);
EVP_cleanup();
ERR_free_strings();
return 0;
}
evp_ecdsa_crypt.cpp
/**
* ecdsa.c
* ECDSA Program for OpenSSL
* written by blanclux
* This software is distributed on an "AS IS" basis WITHOUT WARRANTY OF ANY KIND.
*/
#include <stdio.h>
#include <string.h>
#include "openssl/crypto.h"
#include "openssl/ecdsa.h"
#include "openssl/ec.h"
#include "openssl/evp.h"
#include "openssl/obj_mac.h"
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#define EC_NAME "prime192v1"
#define EC_NID NID_X9_62_prime192v1
static void
printHex(const char *title, const unsigned char *s, int len)
{
int n;
printf("%s:", title);
for (n = 0; n < len; ++n) {
if ((n % 16) == 0) {
printf("\n%04x", n);
}
printf(" %02x", s[n]);
}
printf("\n");
}
int
do_ecdsa(int nid)
{
EC_KEY *eckey = NULL;
EC_GROUP *group;
unsigned char digest[20];
unsigned char *signature = NULL;
unsigned int sigLen;
int ret = 1;
int degree;
/* fill digest values with some random data */
if (!RAND_pseudo_bytes(digest, 20)) {
fprintf(stderr, "ERROR: unable to get random data\n");
goto err;
}
/* create new ecdsa key (== EC_KEY) */
if ((eckey = EC_KEY_new()) == NULL) {
goto err;
}
group = EC_GROUP_new_by_curve_name(nid);
if (group == NULL) {
goto err;
}
if (EC_KEY_set_group(eckey, group) == 0) {
goto err;
}
EC_GROUP_free(group);
degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
if (degree < 160) {
fprintf(stderr, "Skip the curve %s (degree = %d)\n",
OBJ_nid2sn(nid), degree);
goto err;
}
/* create key */
if (!EC_KEY_generate_key(eckey)) {
fprintf(stderr, "EC_KEY_generate_key failed.\n");
goto err;
}
/* check key */
if (!EC_KEY_check_key(eckey)) {
fprintf(stderr, "EC_KEY_check_key failed.\n");
goto err;
}
/* create signature */
sigLen = ECDSA_size(eckey);
if ((signature = OPENSSL_malloc(sigLen)) == NULL) {
goto err;
}
if (!ECDSA_sign(0, digest, 20, signature, &sigLen, eckey)) {
fprintf(stderr, "ECDSA_sign failed.\n");
goto err;
}
printHex("Sign", signature, sigLen);
printf("sigLen = %d\n", sigLen);
/* verify signature */
if (ECDSA_verify(0, digest, 20, signature, sigLen, eckey) != 1) {
fprintf(stderr, "ECDSA_verify failed.\n");
goto err;
}
ret = 0;
err:
EC_KEY_free(eckey);
OPENSSL_free(signature);
return ret;
}
int
do_ecdsa_evp(int nid)
{
int ret = 1;
EC_KEY *eckey = NULL; /* EC key pair */
EVP_PKEY *evp_key = NULL; /* EVP private key */
EVP_MD_CTX *evpx = NULL; /* EVP_MD context */
const EVP_MD *md = NULL; /* Message Digest */
unsigned char *mesg;
unsigned int mesgLen = 32;
unsigned char *signature = NULL;
unsigned int sigLen = 0;
eckey = EC_KEY_new_by_curve_name(nid);
if (eckey == NULL) {
goto err;
}
/* EC key pair */
if (!EC_KEY_generate_key(eckey)) {
goto err;
}
/* Private key */
if ((evp_key = EVP_PKEY_new()) == NULL) {
goto err;
}
if (!EVP_PKEY_set1_EC_KEY(evp_key, eckey)) {
goto err;
}
/* EVP_MD context */
if ((evpx = EVP_MD_CTX_create()) == NULL) {
goto err;
}
/* EVP Message Digest type */
if ((md = EVP_ecdsa()) == NULL) {
goto err;
}
mesg = (unsigned char*)OPENSSL_malloc(mesgLen);
if (!RAND_pseudo_bytes(mesg, mesgLen)) {
fprintf(stderr, "ERROR: unable to get random data\n");
goto err;
}
/* Signature area */
sigLen = EVP_PKEY_size(evp_key);
signature = (unsigned char *) OPENSSL_malloc(sigLen);
if (signature == NULL) {
goto err;
}
printf("sigLen = %d\n", sigLen);
printf("mesgLen = %d\n", mesgLen);
/* Signature generation */
/* Init */
if (!EVP_SignInit_ex(evpx, md, NULL)) {
fprintf(stderr, "EVP_SignInit error\n");
goto err;
}
/* Update */
if (!EVP_SignUpdate(evpx, mesg, mesgLen)) {
fprintf(stderr, "EVP_SignUpdate error\n");
goto err;
}
/* Final */
if (!EVP_SignFinal(evpx, signature, &sigLen, evp_key)) {
fprintf(stderr, "EVP_SignFinal error.\n");
goto err;
}
printHex("Sign", signature, sigLen);
printf("sigLen = %d\n", sigLen);
/* Verify signature */
/* Init */
if (!EVP_VerifyInit_ex(evpx, md, NULL)) {
fprintf(stderr, "EVP_VerifyInit error\n");
goto err;
}
/* Update */
if (!EVP_VerifyUpdate(evpx, mesg, mesgLen)) {
fprintf(stderr, "EVP_VerifyUpdate error.\n");
goto err;
}
/* Final */
ret = EVP_VerifyFinal(evpx, signature, sigLen, evp_key);
if (ret != 1) {
fprintf(stderr, "EVP_VerifyFinal error.\n");
goto err;
}
ret = 0;
err:
EVP_PKEY_free(evp_key);
EC_KEY_free(eckey);
EVP_MD_CTX_destroy(evpx);
OPENSSL_free(mesg);
OPENSSL_free(signature);
return ret;
}
int
main(int argc, char *argv[])
{
int nid = EC_NID;
int ret;
char *name = NULL;
if (argc == 2 && strcmp(argv[1], "-h") == 0) {
printf("usage: ecdsa [nID [EC curve name]]\n");
return 1;
}
if (argc >= 2) {
nid = atoi(argv[1]);
}
if (argc == 3) {
name = argv[2];
}
printf("< ECDSA Test >\n");
printf("NID: %s\n", OBJ_nid2sn(nid));
ret = do_ecdsa(nid);
if (ret == 0) {
printf("OK\n");
} else {
printf("NG (ret = %d)\n", ret);
}
printf("\n");
printf("< ECDSA_EVP Test >\n");
if (name == NULL ) {
printf("NID: %s\n", EC_NAME);
ret = do_ecdsa_evp(EC_NID);
} else {
ret = do_ecdsa_evp(OBJ_sn2nid(name));
}
if (ret == 0) {
printf("OK\n");
} else {
printf("NG (ret = %d)\n", ret);
}
return 0;
}