openssl rsa encryption decryption 예제 코드
본 글은 openssl 라이브러 api를 사용하여 public / private key를 이용한 암호화/
복호화 예제 코드를 싣고 있다.
RSA Key는 파일에서 불러오며, "hello openssl crypto!!" 문자를 public key를 사용하여 암호화
하였고, private key를 사용해 복호화 했다. 키를 파일에서 불러오고,
암호화/복호화 하는 기능은 별도의 API로 만들었으며, 사용 방법은 main 함수를
참조하면 된다.
[소스코드]
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/pem.h>
#define safe_free(x) if(x){free(x);x=NULL;}
#define rsa_public_key 0
#define rsa_private_key 1
typedef struct _rsa_ctx_t
{
RSA *rsa_key;
int key_type;
int ras_modulus_size;
}rsa_ctx_t;
RSA *ras_loadkey(char *key_path, int key_type);
rsa_ctx_t *rsa_init(char *key_path, int
key_type);
int rsa_get_max_encryped_size(rsa_ctx_t *ctx);
int rsa_encryption(rsa_ctx_t *ctx, unsigned
char *in, int inlen, unsigned char *out, int outsize);
int rsa_decryption(rsa_ctx_t *ctx, unsigned
char *in, int inlen, unsigned char *out, int outsize);
void rsa_deinit(rsa_ctx_t *ctx);
/*파일에서 키를 불러오는 온다.
*/
RSA *ras_loadkey(char *key_path, int key_type)
{
#define MINBITS 1024
#define MAXBITS 8192
RSA *_rsa = NULL;
BIO *_bio = NULL;
EVP_PKEY *pkey = NULL;
if(!key_path) return NULL;
_bio = BIO_new(BIO_s_file());
if(!_bio) return NULL;
if (BIO_read_filename(_bio,
key_path) == 1)
{
if(key_type == rsa_public_key)
{
pkey = PEM_read_bio_PUBKEY(_bio,
NULL, NULL, NULL);
}
else if(key_type ==
rsa_private_key)
{
pkey =
PEM_read_bio_PrivateKey(_bio, NULL, NULL, NULL);
}
if(pkey)
{
_rsa = EVP_PKEY_get1_RSA(pkey);
if (_rsa)
{
RSA_up_ref(_rsa);
}
EVP_PKEY_free(pkey);
pkey = NULL;
}
if (_rsa == NULL)
{
printf("[%s] Unable to get RSA key
from file\n",__func__);
}
}
else
{
printf("[%s] BIO_read_filename %s
fail \n",__func__, key_path);
}
BIO_free(_bio);
if (_rsa)
{
int strength =
BN_num_bits(_rsa->n);
if (strength < MINBITS ||
strength > MAXBITS)
{
RSA_free(_rsa);
_rsa = NULL;
printf("[%s] Invalid
key\n",__func__);
}
}
return _rsa;
}
rsa_ctx_t *rsa_init(char *key_path, int key_type)
{
rsa_ctx_t *ctx = NULL;
if(!key_path) return NULL;
ctx =
(rsa_ctx_t*)malloc(sizeof(rsa_ctx_t));
if(ctx)
{
memset(ctx,0,sizeof(rsa_ctx_t));
ctx->key_type = key_type;
ctx->rsa_key =
ras_loadkey(key_path,key_type);
if(ctx->rsa_key == NULL)
{
rsa_deinit(ctx);
return NULL;
}
ctx->ras_modulus_size =
RSA_size(ctx->rsa_key);
}
return ctx;
}
int rsa_get_max_encryped_size(rsa_ctx_t *ctx)
{
if(ctx)
{
return ctx->ras_modulus_size;
}
return 0;
}
int rsa_encryption(rsa_ctx_t *ctx, unsigned char *in, int inlen, unsigned
char *out, int outsize)
{
int size = 0;
if(!ctx || inlen <= 0 || !in ||
!out || outsize <= 0) return -1;
if(outsize <
ctx->ras_modulus_size)
{
printf("[%s] outsize %d <
ctx->ras_modulus_size %d\n",__func__,outsize,ctx->ras_modulus_size);
return -1;
}
if(ctx->key_type ==
rsa_public_key)
{
size = RSA_public_encrypt(inlen,
in, out, ctx->rsa_key, RSA_PKCS1_PADDING);
}
else if(ctx->key_type ==
rsa_private_key)
{
size = RSA_private_encrypt(inlen,
in, out, ctx->rsa_key, RSA_PKCS1_PADDING);
}
return size;
}
int rsa_decryption(rsa_ctx_t *ctx, unsigned char *in, int inlen, unsigned
char *out, int outsize)
{
int size = 0;
if(!ctx || inlen <= 0 || !in ||
!out || outsize <= 0) return -1;
if(ctx->key_type ==
rsa_public_key)
{
size = RSA_public_decrypt(inlen,
in, out, ctx->rsa_key, RSA_PKCS1_PADDING);
}
else if(ctx->key_type ==
rsa_private_key)
{
size = RSA_private_decrypt(inlen,
in, out, ctx->rsa_key, RSA_PKCS1_PADDING);
}
return size;
}
void rsa_deinit(rsa_ctx_t *ctx)
{
if(ctx)
{
if(ctx->rsa_key)
{
RSA_free(ctx->rsa_key);
ctx->rsa_key = NULL;
}
free(ctx);
}
}
int main(int argc, char** argv)
{
rsa_ctx_t *public_rsa =
rsa_init("./PublicKey.pem",rsa_public_key);
rsa_ctx_t *private_rsa =
rsa_init("./PrivateKey.pem",rsa_private_key);
int max_encryped_data_size = 0;
int i = 0;
unsigned char test_msg[] =
"hello openssl crypto!!";
unsigned char *crypted_msg =
NULL;
unsigned char *decrypted_msg =
NULL;
if( public_rsa!= NULL &&
private_rsa != NULL)
{
max_encryped_data_size =
rsa_get_max_encryped_size(public_rsa);
crypted_msg = (unsigned char*)
malloc(sizeof(unsigned char)*max_encryped_data_size);
decrypted_msg = (unsigned char*)
malloc(sizeof(unsigned char)*max_encryped_data_size);
if(crypted_msg &&
decrypted_msg)
{
int crypted_len = 0;
int decrypted_len = 0;
memset(crypted_msg,0,sizeof(unsigned char)*max_encryped_data_size);
memset(decrypted_msg,0,sizeof(unsigned char)*max_encryped_data_size);
crypted_len =
rsa_encryption(public_rsa,test_msg,strlen((char*)test_msg),crypted_msg,max_encryped_data_size);
if( crypted_len > 0)
{
printf("rsa_encryption using
public key\n");
printf("in : %s\n",test_msg);
printf("out : ");
for(i=0;i<crypted_len;i++)
printf("%x",crypted_msg[i]);
printf("\n");
}
else
{
printf("rsa_encryption using
public key fail\n");
}
decrypted_len =
rsa_decryption(private_rsa,crypted_msg,crypted_len,decrypted_msg,max_encryped_data_size);
if(decrypted_len > 0)
{
printf("\nrsa_decryption using
private key\n");
printf("in : ");
for(i=0;i<crypted_len;i++)
printf("%x",crypted_msg[i]);
printf("\n");
printf("out :
%s\n",decrypted_msg);
}
else
{
printf("rsa_decryption using
private key fail\n");
}
}
}
safe_free(decrypted_msg);
safe_free(crypted_msg);
if (public_rsa)
{
rsa_deinit(public_rsa);
public_rsa = NULL;
}
if (private_rsa)
{
rsa_deinit(private_rsa);
private_rsa = NULL;
}
return 0;
}
[빌드]
gcc -o rsacrypto rsacrypt.c -lssl -lcrypto
[실행 결과]
이전에 올린적 있는
rsakeygen을 사용하여 생성된 키를 사용하였다.
[관련 포스트]
댓글
댓글 쓰기