OpenSSL
라이브러리를 사용하기 위해 libssl-dev를 설치한다.
$ sudo apt -y install libssl-dev
컴파일 시 libcrypto.so, libssl.so을 링킹하여 컴파일한다.
2048길이의 RSA 키
를 생성한다.
이후 32byte의 키값을 통해서 개인키
를 암호화하여 저장한다.
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
int main(void) {
BIGNUM *bignum = NULL;
ERR_clear_error();
if ((bignum = BN_new()) == NULL) {
printf("BN_new error : %s\n", ERR_error_string(ERR_get_error(), NULL));
return EXIT_FAILURE;
}
if(BN_set_word(bignum, RSA_F4) != 1) {
printf("BN_set_word error : %s\n", ERR_error_string(ERR_get_error(), NULL));
BN_clear_free(bignum);
return EXIT_FAILURE;
}
RSA *rsa = NULL;
if ((rsa = RSA_new()) == NULL) {
printf("RSA_new error : %s\n", ERR_error_string(ERR_get_error(), NULL));
BN_clear_free(bignum);
return EXIT_FAILURE;
}
if (RSA_generate_key_ex(rsa, 2048, bignum, NULL) != 1) {
printf("RSA_generate_key_ex error : %s\n", ERR_error_string(ERR_get_error(), NULL));
BN_clear_free(bignum);
return EXIT_FAILURE;
}
BN_clear_free(bignum);
FILE *PrivateFilePointer = fopen("./private.key", "wb");
if (PrivateFilePointer == NULL) {
perror("private.key open fail");
RSA_free(rsa);
rsa = NULL;
return EXIT_FAILURE;
}
unsigned char KEY[32] = { 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08 };
if(PEM_write_RSAPrivateKey(PrivateFilePointer, rsa, EVP_aes_256_cbc(), KEY, sizeof(KEY), NULL, NULL) != 1)
{
printf("PEM_write_RSAPrivateKey error : %s\n", ERR_error_string(ERR_get_error(), NULL));
fclose(PrivateFilePointer);
PrivateFilePointer = NULL;
RSA_free(rsa);
rsa = NULL;
return EXIT_FAILURE;
}
fclose(PrivateFilePointer);
PrivateFilePointer = NULL;
RSA_free(rsa);
return 0;
}
암호화된 개인키를 로드한 뒤 인증서
를 생성
하기 위해 사용한다.
이후 인증서 정보를 생성하고 자체 서명
을 통해 생성한 인증서를
파일로 저장해본다.
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <string.h>
int password_cb(char *pcszBuff,int size,int rwflag, void *pPass)
{
size_t unPass = strlen((char*)pPass);
if(unPass > (size_t)size) unPass = (size_t)size;
memcpy(pcszBuff, pPass, unPass);
return (int)unPass;
}
int main(void) {
unsigned char key[32] = { 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08 };
FILE *fp = fopen("private.key", "r");
if (!fp) {
printf("File Open Error\n");
return EXIT_FAILURE;
}
EVP_PKEY* pkey = PEM_read_PrivateKey(fp, NULL, password_cb, (void *)key);
if (!pkey) {
printf("BN_new error : %s\n", ERR_error_string(ERR_get_error(), NULL));
return EXIT_FAILURE;
}
X509 *x509 = NULL;
if ((x509 = X509_new()) == NULL) {
printf("X509_new error : %s\n", ERR_error_string(ERR_get_error(), NULL));
EVP_PKEY_free(pkey);
return EXIT_FAILURE;
}
X509_set_version(x509, 2);
ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)time(NULL));
X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), (long)(60 * 60 * 24 * 365));
X509_set_pubkey(x509, pkey);
X509_NAME *name = NULL;
if ((name = X509_NAME_new()) == NULL) {
printf("X509_NAME_new error : %s\n", ERR_error_string(ERR_get_error(), NULL));
EVP_PKEY_free(pkey);
X509_free(x509);
return EXIT_FAILURE;
}
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"KR", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"World", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_ASC, (unsigned char *)"X509", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"2jinu", -1, -1, 0);
X509_set_issuer_name(x509, name);
if(X509_sign(x509, pkey, EVP_sha256()) == 0) {
printf("X509_sign error : %s\n", ERR_error_string(ERR_get_error(), NULL));
EVP_PKEY_free(pkey);
X509_free(x509);
return EXIT_FAILURE;
}
EVP_PKEY_free(pkey);
FILE *CertificateFilePointer = fopen("./certificate.crt", "wb");
if (CertificateFilePointer == NULL) {
perror("certificate.crt open fail");
X509_free(x509);
return EXIT_FAILURE;
}
if(PEM_write_X509(CertificateFilePointer, x509) != 1) {
printf("PEM_write_X509 error : %s\n", ERR_error_string(ERR_get_error(), NULL));
X509_free(x509);
fclose(CertificateFilePointer);
return EXIT_FAILURE;
}
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
EVP_cleanup();
return 0;
}