제 2 장기초암호화 기법 컴퓨터시스템보안금오공과대학교컴퓨터공학부최태영
평문과암호문 평문 (plaintext) : 암호화되기전의읽을수있는문장 암호문 (ciphertext) : 암호화에의해서읽을수없게된문장 암호화 (encryption) : 평문을암호문으로바꾸는과정 암호화알고리즘 : 암호화수행과정 복호화 (decryption) : 암호문을평문으로바꾸는과정 복호화알고리즘 : 복호화수행과정 2
암호작성법 (Cryptography) 보내는사람공개된환경받는사람 평문암호화암호문복호화평문 키 1 키 2 동일 3
암호관련추가용어 암호알고리즘 (cryptography algorithm) 암호화알고리즘 + 복호화알고리즘 키 (key) 암호알고리즘에사용되는비밀정보 합법적인사용자와그렇지않은자를구분 복호화에사용되는키는비밀보관해야함 암호해독 (cryptanalysis) 키를모르는상태에서암호문을평문으로바꾸거나키를찾아내는것 암호해독자 (cryptanalist) 암호해독을시도하는자 4
암호작성법의수식화 C = E(P, K e ) P : 평문 C : 암호문 K e : 암호화에사용되는키 E : 암호화알고리즘 P = D(C, K d ) K d : 복호화에사용되는키 D : 복호화알고리즘 C C if P P and C = E(P, K e ) 5
브루트포스공격 (bruteforce attack) 암호문 다양한키시도 복호화 암호해독의한가지방법 평문 6
시저암호 (Caesar cipher) 시저암호 : 각알파벳문자를자신의세번째뒤알파벳으로바꾸는암호방식 general you attack the enemy at the west field at three o clock am a b c d e f g h i j k l m n o p q r s t u v w x y z d e f g h i j k l m n o p q r s t u v w x y z a b c jhghudo brx dwwdfn wkh hghpb dw wkh zhvw ilhog dw wkuhh r'forfn dp 7
시저암호의일반화 치환암호 (substitution cipher) 단순치환암호 (simple substitution cipher) k- 번째다음알파벳으로변경 1- 번째알파벳암호화 : t i = (t i + k) mod 26 공격이쉬움 ( 다음페이지 ) 키공간이작음 : 가능한키의개수가 25 개 모노알파벳암호 (monoalphabetic cipher) 8
9
모노알파벳암호 각알파벳을다른알파벳으로바꾸는암호화방식 키공간의크기는 26! 4 ⅹ 10 26 초당 10 10 개키처리컴퓨터에서 10 11 년소요 사용빈도가높은알파벳이나문자열이존재 : E, T, TH, ST, 암호문에서사용빈도가높은알파벳을 E, T 등으로교체시도 10
전치암호 (transposition cipher) 평문에서알파벳들의위치를어떤규칙을사용하여변경하는암호알고리즘 대표적인전치암호로는행렬에열방향으로문자들을입력한뒤행방향으로읽어서암호문으로출력하는방법이있음 Columnar 전치암호 열의입력순서와행의출력순사가다름 11
전치암호의암호화 west field at three oclock am w e s t f i e l d a t t h r e e o c l o c k a m wfdhoc eiarck setela tlteom 12
전치암호의복호화 wfdhoc eiarck setela tlteom w e s t f i e l d a t t h r e e o c l o c k a m 13
Columnar 전치암호의예 2 1 3 4 4 h r e e 3 d a t t 1 w e s t 5 o c l o 2 f i e l 6 c k a m raecik hdwofc etslea ettolm 14
일회성암호 One-Time Pad, OTP Vernam cipher 평문의각비트를난수비트스트림 (ramdom bit stream) 과 xor 연산을수행 15
일회성암호의구조 보내는사람 동일 받는사람 One-time-pad One-time-pad 평문 암호문 평문 동일 16
w e s t 평문 1110111 1100101 1110011 1110100 보내는사람 원타임패드 1001101 1011100 0010110 0100010 암호문 0111010 0111001 1100101 1010110 = 원타임패드 1001100 1011100 0010110 0100010 = 받는사람 평문 1110111 1100101 1110011 1110100 w e s t 17
일회성암호의문제점 난수비트스트림은평문의크기와같아야함 난수비트스트림을상대방에게안전하게제공하는것은어려움 유사난수스트림을사용함 안전성하락 18
변형된일회성암호 보내는사람 받는사람 동일 key key 난수생성기 난수생성기 평문 암호문 평문 동일 19
키의특성에따른암호분류 대칭키암호 (Symmetric cipher) 암호화와복호화에사용되는키가동일하거나, 한키로부터다른키를쉽게생성 비대칭키암호 (Asymmetric cipher) 암호화와복호화에사용되는키가다르며, 한키로부터다른키를유도하기가어려움 공개키 : 암호화에사용, 공개되는키 개인키 : 복호화에사용, 비공개 20
암호화처리크기에따른분류 블록암호 (block cipher) 2 비트이상의일정크기평문블록을한꺼번에암호화 혼돈과확산이잘됨 스트림암호 (stream cipher) 한번에한비트씩암호화 일회성암호 혼돈만적용됨 21
혼돈과확산 암호학자 Claude Shannon 이제안 혼돈 (confusion) 키와암호문이얽혀있는정도 확산 (diffusion) 평문이암호문에흩뿌려져있는정도 전송되는암호문에오류가발생할경우그오류가전파 (propagate) 되는경향이있음 22
OpenSSL 의키생성 커맨드라인명령어를통한키생성 대칭키생성 공개키생성 (RSA 키생성 ) 라이브러리를이용한키생성 대칭키생성 공개키생성 23
대칭키생성 예제 : openssl rand 8 -out key.sec 문법 : openssl rand [-out file] [- rand file(s)] [-base64] num -out : 저장파일지정 -rand : 시드파일지정 -base64 : 출력가능형태여부지정 num : 생성할키의바이트길이 24
RSA 공개키생성 예시 : openssl genrsa -out privkey.pem 문법 : openssl genrsa [-out file] [- passout arg] [-des] [-des3] [-idea] [- f4] [-3] [-rand file(s)] [-engine id] [numbits] -out : 개인키저장파일명시 -passout : 개인키파일암호화키명시 -rand: 난수시드파일명시 -engine : 사용자개발암호알고리즘명시 numbits : 모듈러스크기명시 25
RSA 키관리 예시 : openssl rsa -pubout < privkey.pem > pubkey.pem 문법 : openssl rsa [-inform PEM NET DER] [-outform PEM NET DER] [-in file] [-passin arg] [- out file] [-passout arg] [-sgckey] [-des] [-des3] [-idea] [-text] [-noout] [- modulus] [-check] [-pubin] [-pubout] [- engine id] -inform outform : 키파일저장형식 26
라이브러리를통한비밀키생성 예시 RAND_seed(seedbuf, 8); RAND_bytes(randbuf, 16); 설명 seedbuf 는난수시드를포함하며난수자료구조에시드값을전달하는데사용. randbuf 는생성된난수가저장되는공간 seedbuf 를만드는방법으로현재시간을사용할수있음 27
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <time.h> #include <string.h> #include <assert.h> #include <openssl/rand.h> #define MAXBUFF 128 void printstr(void *buf, int size){ /* 한캐릭터씩 16 진수로출력하는함수 */ } void gettimesubstr(char buff[]) { struct timeval atime; struct timezone tzone; gettimeofday(&atime, &tzone); memcpy(buff, &(atime.tv_sec), 4); memcpy(buff+4, &(atime.tv_usec), 4); } 28
int main(void) { char seedbuf[maxbuff]; char randbuf[maxbuff]; } gettimesubstr(seedbuf); RAND_seed(seedbuf, 8); RAND_bytes(randbuf, 16); printstr(randbuf, 16); exit(0); 29
라이브러리를통한공개키생성 예시 rsapriv = RSA_generate_key(512, RSA_F4, NULL, NULL); rsapub = RSAPublicKey_dup(rsaPriv); PEM_write_RSAPublicKey(pubf, rsapub); PEM_write_RSAPrivateKey(privf, rsapriv, NULL, NULL, 0, NULL, NULL) 30
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <time.h> #include <string.h> #include <assert.h> #include <openssl/rand.h> #include <openssl/rsa.h> #include <openssl/pem.h> #define MAXBUFF 128 void gettimesubstr(char buff[]) { struct timeval atime; struct timezone tzone; } gettimeofday(&atime, &tzone); memcpy(buff, &(atime.tv_sec), 4); memcpy(buff+4, &(atime.tv_usec), 4); 31
int main(void) { RSA *rsapriv = NULL, *rsapub = NULL; char seedbuf[maxbuff]; FILE *pubf, *privf; gettimesubstr(seedbuf); RAND_seed(seedbuf, 8); rsapriv = RSA_generate_key(512, RSA_F4, NULL, NULL); if (rsapriv == NULL){ fprintf(stderr, "RSA generate key error.\n"); return(0); } rsapub = RSAPublicKey_dup(rsaPriv); if (rsapub == NULL){ fprintf(stderr, "RSA public key copy error.\n"); return(0); } 32
pubf = fopen("pubkey.pem", "w"); assert(pubf); privf = fopen("privkey.pem", "w"); assert(privf); if (!PEM_write_RSAPublicKey(pubf, rsapub)) fprintf(stderr, public key to file fails.\n"); if (!PEM_write_RSAPrivateKey(privf, rsapriv, NULL, NULL, 0, NULL, NULL)) fprintf(stderr, private key to file fails.\n"); fclose(pubf); fclose(privf); } RSA_free(rsaPriv); RSA_free(rsaPub); exit(0); 33