US0
(미완) [OpenSSL/ECDH] ECDH Cryptography Part1. (Serialization /Deserialization) 본문
(미완) [OpenSSL/ECDH] ECDH Cryptography Part1. (Serialization /Deserialization)
us0 2018. 11. 29. 11:15[OpenSSL/ECDH] ECDH Cryptography Part1.
(Serialization /Deserialization)
이번 포스팅은 ECDH 에 대해서 알아보자!! (코드 한번에 나와있는곳은 맨 마지막 부분!!)
ECDH알고리즘이란??
타원 곡성 암호 blahblah... (추가시키기)
EVP API를 이용하기위해 <openssl/evp.h>
Random한 값을 얻기위해 <openssl/rand.h>
ECDH 를 이용할거니까 <openssl/ec.h>
이라는 각각의 헤더 파일을 선언 해준다!!!
#include<openssl/evp.h>
#include<openssl/ec.h>
#include<openssl/rand.h>
원활한 코드 설명을 위해 main공간에 모든코드 넣어보겠다 ❛˓◞˂̵✧
int main(void){
// Generate EC domain param(EC domainarameter 생성!!
/* Create the context for parameter generation */
EVP_PKEY_CTX *pctx = NULL;
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); //컨텍스트에 EC를 이용한다 말해준다.
//EVP_PKEY_CTX_new_id(<#int id#>, <#ENGINE *e#>)
printf("EVP_PKEY_EC : %d\n",EVP_PKEY_EC);
<<output>>
EVP_PKEY_EC : 408
그리고 항상 컨텍스트 등 할당하는 코드가 있으면 해당 메모리가 잘 만들어졌는지 아래처럼 If문을 작성해주자!!
그리고 키 생성 및 특정한 값을 할당 해주는 함수를 호출할때에도 if 문을 빼먹지 말자!!
<<이것은 당연하기 때문에 설명할 땐 잠시 생략하겠다. ❛˓◞˂̵✧ >>
Ex)
if(pctx == NULL){
printf("EVP_PKEY_CTX_new_id error\n");
return -1;
}
--------------------------------------------다시 시작 ❛˓◞˂̵✧ ---------------------------------------------
타원곡선의 공식은
y^2 = x^3 + ax + b (mod p) 이다!!
따라서 a, b, p 값을 정해줘야 하는데 아래 코드가 이 a, b, p 를할당해주는 코드이다!!
EVP_PKEY_paramgen_init(pctx);
ECDH는 위의 식을 이용하여 y값을 도출하면 y^2을 구했으니 y값은 2개가 나올것이다!! 이를 각각 P1, P2라고 해준다.
(why?? 예를 들어 4를 예로 들면 (+2)^2= 4 와 (-2)^2 = 4 가 나오듯!!)
P3은 P3 = P1 + P2 인데 더하는 방법이 여러가지 이다 따라서 아래코드를 작성!!
EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1);
여기서 부터는 어떠한 곡선 그래프(방정식)를 이용할 것인지 방정식을 2번째 매개변수로 알려준다 .
여기서는 NID_X9_62_prime256v1 를 이용하고 있다.
지금까지 Param을 생성 해줬으니 이 소식을 알고있는 pctx 변수를 불러서 Key를 보관하는 EVP_PKEY 변수를 생성해줘서 보관해준다.
EVP_PKEY *params = NULL;
EVP_PKEY_paramgen(pctx, ¶ms)
이렇게 하면
y^2 = x^3 + ax + b (mod p) 에서 y, x, b, p 값이 모두 어떤 값인지 알게 된다!!
그리고 P1, P2, P3 도 알게된다 이 모든 정보들은 pctx 변수에있고,
키에 관련된 정보들만 따로 EVP_PKEY *param 변수에 저장 된다.
여기서 잠깐!!!! =============================================
EVP_PKEY란??
EVP_PKEY 객체는 관련 알고리즘 및 매개 변수와 함께 공개 키 및 개인 키 (선택 사항)를 저장하는 데 사용됩니다. 그들은 또한 대칭 MAC 키를 저장할 수 있습니다.
다음과 같은 EVP_PKEY 유형이 지원됩니다.
- EVP_PKEY_EC : 타원 곡선 키 (ECDSA 및 ECDH 용) - 서명 / 검증 작업 및 키 유도 지원
- EVP_PKEY_RSA : RSA - 서명 / 확인 및 암호화 / 해독을 지원합니다.
- EVP_PKEY_DH : Diffie Hellman - 키 유도 용
- EVP_PKEY_DSA : 서명 / 확인을위한 DSA 키
- EVP_PKEY_HMAC : 메시지 인증 코드를 생성하기위한 HMAC 키
- EVP_PKEY_CMAC : 메시지 인증 코드를 생성하기위한 CMAC 키
출처 : OpensslWiki ( https://wiki.openssl.org/index.php/EVP )
=========================================================
Alice & Bob KeyPair(Public key, Private key) Generate
앨리스와 밥의 public key와 private Key 쌍인 KeyPair를 생성하는 시간이다 화팅 ❛˓◞˂̵✧
Alice KeyPair
먼저 키에관한 정보를 담을 수 있는 컨텍스트(EVP_PKEY_CTX 구조체) 를 생성 해준다.
그리고 여기에 param << 아까 구했던 ECDH 키들 을 이용해 새로운 PKEY컨텍스트 생성!!
그럼 kctx는 param 정보를 담고 있는 컨텍스트가 된다!!
EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new(params, NULL);
if( kctx == NULL){
printf("EVP_PKEY_CTX_new error\n");
return -1;
}
그럼 Param정보를 담고 있는 Kctx를 EVP_PKEY_keygen_init 이 함수를 통해 키 담을 공간을 초기화 시켜준다.
/* Generate my EC key pair using kctx */
if( EVP_PKEY_keygen_init(kctx) !=1 ){
printf("EVP_PKEY_keygen_init error!!\n");
return -1;
}
그리고 kctx 컨텍스트에 저장된 정보를 EVP_PKEY_keygen(kctx, &alice_keypair) 함수를 통해 alice의 Keypair에 저장해준다.
EVP_PKEY *alice_keypair = NULL;
if(EVP_PKEY_keygen(kctx, &alice_keypair) != 1){
printf("EVP_PKEY_keygen error!!\n");
return -1;
}
BOB_KeyPair
/*********************************BOB*********************************/
/*
* Generate Bob's private and public key pair
*/
/* Create the context for key generation */
kctx = EVP_PKEY_CTX_new(params, NULL);
if( kctx == NULL){
printf("EVP_PKEY_CTX_new error\n");
return -1;
}
/* Generate my EC key pair using kctx */
if( EVP_PKEY_keygen_init(kctx) !=1 ){
printf("EVP_PKEY_keygen_init error!!\n");
return -1;
}
EVP_PKEY *bob_keypair = NULL;
if(EVP_PKEY_keygen(kctx, &bob_keypair) != 1){
printf("EVP_PKEY_keygen error!!\n");
return -1;
}
그럼 각각의 KeyPair가 이루어 졌으니 Public Key와 Private Key를 갈라볼까?!?!?!?!!!!
Serialization
자 공개 키를 나누기 위해 EC(타원 곡선)는 어떤 과정을 거쳐야할까??
구조체,자료형 이름 (상태) <변수명>
EVP_PKEY (key pair) <peerkey>
|
|
EC_KEY (key pair) <peer_eckey>
|
|
EC_POINT (public key) <peer_pub_ecpoint>
|
|
char * (string) <peerPubkeyChar>
Alice_ECDH_Secret_Key생성을 위해 먼저 Bob의 Public Key를 도출해보자!!
여기서 잠깐!!!!!
Q. Alice_ECDH_Secret_Key는 어떻게 만들어지나용??
A. <<Alice_ECDH_Secret_Key = Bob's_public_key * Alice_Private_key * P >>
bob_keypair는 위에서 만들어 줬으니 EC_KEY부터 생성해보자!!
EC_KEY *bob_eckey = EVP_PKEY_get1_EC_KEY(bob_keypair);
이것은 EVP_PKEY_CTX인 bob_keypair에서 EC_KEY와 연관된 애들을 추출하는 과정!!
그리고 타원곡선에서의 Point(아까 말했던 P3!!) 를 알아내기 위해 EC_POINT를 추출해보자!!
const EC_POINT *bob_pubkey_ecpoint = EC_KEY_get0_public_key(bob_eckey);
그리고 밥의 public_key 공간을 할당해주기위해 버퍼길이를 생성해주고 이를 사용해 메모리를 동적할당해준다!!
size_t bufLen = EC_POINT_point2oct(EC_KEY_get0_group(bob_eckey), bob_pubkey_ecpoint, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL);
unsigned char *bob_pub_char = (unsigned char *)malloc(bufLen);
그리고 이함수를 한번 더 호출해줘서 bob_pub_char에 저장 해준다.
EC_POINT_point2oct(EC_KEY_get0_group(bob_eckey), bob_pubkey_ecpoint, POINT_CONVERSION_COMPRESSED,bob_pub_char, bufLen, NULL);
Deserialization
'Security > Cryptography' 카테고리의 다른 글
[OpenSSL/RSA] 나눴던 Private Key로 다시 RSA구조체 만들고 암/복호화 하기!!(Deserialization) (0) | 2018.11.24 |
---|---|
[OpenSSL/RSA] RSA Private key와 Public key 나누기!!(Serialization) (0) | 2018.11.21 |
[OpenSSL/RSA] RSA Sructure & Function (0) | 2018.11.15 |
CH.5 Openssl를 활용한 암호화 프로그래밍<EVP API를 활용한 AES_CBC 암호화 ver.1.> (1) | 2018.11.10 |
[OpenSSL] <openssl/evp.h>EVP 함수 정리 (0) | 2018.11.10 |