公開鍵認証

```c++: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;
}

```

```c++: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;
}
```