6 eavesdropper attacker cryptography cryptanalysis passive attack active

  • Slides: 63
Download presentation

암호 관련 용어 설명 6 도청자(eavesdropper) 공격자(attacker) 암호설계(cryptography) 암호해독(cryptanalysis) 수동공격(passive attack) 능동공격(active attack)

암호 관련 용어 설명 6 도청자(eavesdropper) 공격자(attacker) 암호설계(cryptography) 암호해독(cryptanalysis) 수동공격(passive attack) 능동공격(active attack)

알고리즘의 독립성 18 같은 인터페이스에 알고리즘 이름만 바꾸어 사용할 수 있도록 구현 try{ Message.

알고리즘의 독립성 18 같은 인터페이스에 알고리즘 이름만 바꾸어 사용할 수 있도록 구현 try{ Message. Digest md 5 = Message. Digest. get. Instance(“MD 5”); // Message. Digest md 5 = Message. Digest. get. Instance(“SHA-1”); md 5. update(buffer); byte[] digest = md 5. digest(); for(int i=0; i<digest. length; i++) System. out. printf(“%02 X ”, digest[i]); } catch(No. Such. Algorithm. Exception e){ e. print. Stack. Trace(); }

의사난수 생성 21 사례 try{ Secure. Random csprng = Secure. Random. get. Instance("SHA 1

의사난수 생성 21 사례 try{ Secure. Random csprng = Secure. Random. get. Instance("SHA 1 PRNG"); boolean rand. Bool = csprng. next. Boolean(); int rand. Int = csprng. next. Int(); byte[] rand. Bytes = new byte[3]; csprng. next. Bytes(random. Bytes); } catch(No. Such. Algorithm. Exception e){ e. print. Stack. Trace(); }

해쉬함수 24 java. security. Message. Digest 엔진을 사용 try{ Message. Digest md 5 =

해쉬함수 24 java. security. Message. Digest 엔진을 사용 try{ Message. Digest md 5 = Message. Digest. get. Instance("MD 5"); md 5. update(plaintext. get. Bytes()); byte[] digest 01 = md 5. digest(); for(byte b: digest 01) System. out. printf("%02 X ", b); System. out. println(); md 5. update(plaintext. get. Bytes()); byte[] digest 02 = md 5. digest(); for(byte b: digest 01) System. out. printf("%02 X ", b); System. out. println(); System. out. printf("Verified = %s%n", Message. Digest. is. Equal(digest 01, digest 02)); } catch(No. Such. Algorithm. Exception e){ e. print. Stack. Trace(); }

두 메시지의 해쉬값 비교 25 public class Digest. Test { public static void main(String[]

두 메시지의 해쉬값 비교 25 public class Digest. Test { public static void main(String[] args) { String plaintext 01 = "This is a simple message. "; String plaintext 02 = "This is a simple message"; try{ Message. Digest md 5 = Message. Digest. get. Instance("MD 5"); md 5. update(plaintext 01. get. Bytes()); byte[] digest 01 = md 5. digest(); for(byte b: digest 01) System. out. printf("%02 X ", b); System. out. println(); md 5. update(plaintext 02. get. Bytes()); byte[] digest 02 = md 5. digest(); for(byte b: digest 02) System. out. printf("%02 X ", b); System. out. println(); System. out. printf("Verified = %s%n", Message. Digest. is. Equal(digest 01, digest 02)); } catch(No. Such. Algorithm. Exception e){ e. print. Stack. Trace(); } } // main } // Digest. Test

MAC 사례 27 try{ Key. Generator kg = Key. Generator. get. Instance("AES"); Secret. Key

MAC 사례 27 try{ Key. Generator kg = Key. Generator. get. Instance("AES"); Secret. Key key = kg. generate. Key(); Secret. Key. Spec key. Spec = new Secret. Key. Spec(key. get. Encoded(), "Hmac. SHA 1"); Mac mac = Mac. get. Instance("Hmac. SHA 1"); mac. init(key. Spec); mac. update(plaintext. get. Bytes()); byte[] digest 01 = mac. do. Final(); for(byte b: digest 01) System. out. printf("%02 X ", b); System. out. println(); mac. init(key. Spec); mac. update(plaintext. get. Bytes()); byte[] digest 02 = mac. do. Final(); for(byte b: digest 01) System. out. printf("%02 X ", b); System. out. println(); System. out. printf("Verified = %s%n", Message. Digest. is. Equal(digest 01, digest 02)); } catch(No. Such. Algorithm. Exception e){ e. print. Stack. Trace(); }

30 Key Spec 변환 � � � generate. Key() 메소드를 이용하여 생성된 키를 바로

30 Key Spec 변환 � � � generate. Key() 메소드를 이용하여 생성된 키를 바로 알고리즘에 사용할 수 없다. 이것을 key specification으로 변환해야 한다. 이 변환은 생성된 키가 알고리즘에 사용하기에 보다 적합하도록 변환하는 것이다. javax. crypto. spec. Secret. Key. Spec 엔진을 사용 Key. Generator kg = Key. Generator. get. Instance("DES"); Secret. Key key = kg. generate. Key(); Secret. Key. Spec key. Spec = new Secret. Key. Spec(key. get. Encoded(), "DES");

33 객체의 초기화 � public void init(int opmode, Key key) Cipher 엔진의 동작모드 (opmode)

33 객체의 초기화 � public void init(int opmode, Key key) Cipher 엔진의 동작모드 (opmode) � � Cipher. ENCRYPT_MODE: 암호화 연산을 사용하고자 할 때 Cipher. DECRYPT_MODE: 복호화 연산을 사용하고자 할 때

암호화 34 방법 1. do. Final() 메소드만 호출 � 암호화하고자 하는 평문의 크기가 작을

암호화 34 방법 1. do. Final() 메소드만 호출 � 암호화하고자 하는 평문의 크기가 작을 경우 String plaintext = "This is a secret message!"; byte[] ciphertext = cipher. do. Final(plaintext. get. Bytes()); 방법 2. 일련의 update() 메소드를 호출한 후에 do. Final() 메소드 호출 � 암호화하고자 하는 평문의 크기가 크거나 나누어져 있을 경우 byte[] ciphertext = new byte[cipher. get. Output. Size(input. length)]; int ct. Length = cipher. update(my. Byte. Array 01, 0, my. Byte. Array 01. length, ciphertext, 0); ct. Length += cipher. update(my. Byte. Array 02, 0, my. Byte. Array 02. length, ciphertext, ct. Length); ct. Length += cipher. do. Final(ciphertext, ct. Length);

DES 암호화 종합 예제 35 try{ Key. Generator kg = Key. Generator. get. Instance("DES");

DES 암호화 종합 예제 35 try{ Key. Generator kg = Key. Generator. get. Instance("DES"); Secret. Key key = kg. generate. Key(); Secret. Key. Spec key. Spec = new Secret. Key. Spec(key. get. Encoded(), "DES"); Cipher cipher = Cipher. get. Instance("DES/ECB/PKCS 5 Padding"); cipher. init(Cipher. ENCRYPT_MODE, key. Spec); String plaintext = "This is a secret message!"; byte[] ciphertext = cipher. do. Final(plaintext. get. Bytes()); for(int i=0; i<ciphertext. length; i++){ System. out. printf("%02 X ", ciphertext[i]); } System. out. println(); cipher. init(Cipher. DECRYPT_MODE, key. Spec); byte[] cleartext = cipher. do. Final(ciphertext); for(int i=0; i<cleartext. length; i++){ System. out. print((char)cleartext[i]); } System. out. println(); } catch(){ }

파일 암호화 37 File. Input. Stream in. File = new File. Input. Stream(new File("input.

파일 암호화 37 File. Input. Stream in. File = new File. Input. Stream(new File("input. txt")); Key. Generator kg = Key. Generator. get. Instance("AES"); Secret. Key key = kg. generate. Key(); Secret. Key. Spec key. Spec = new Secret. Key. Spec(key. get. Encoded(), "AES"); Cipher cipher = Cipher. get. Instance("AES/ECB/No. Padding"); cipher. init(Cipher. ENCRYPT_MODE, key. Spec); final int BLOCKSIZE = cipher. get. Block. Size(); Cipher. Input. Stream cin. File = new Cipher. Input. Stream(in. File, cipher); File. Output. Stream encrypt. Out. File = new File. Output. Stream(new File("output")); byte[] block = new byte[BLOCKSIZE]; int length = cin. File. read(block); while(length!=-1){ encrypt. Out. File. write(block, 0, length); length = cin. File. read(block); } encrypt. Out. File. close(); in. File. close(); cin. File. close();

파일 복호화 38 암호화된 파일을 복호화 : Cipher. Output. Stream 이용 cipher = Cipher.

파일 복호화 38 암호화된 파일을 복호화 : Cipher. Output. Stream 이용 cipher = Cipher. get. Instance("AES/ECB/PKCS 5 Padding"); cipher. init(Cipher. DECRYPT_MODE, key. Spec); File. Input. Stream encrypt. In. File = new File. Input. Stream(new File("output")); File. Output. Stream out. File = new File. Output. Stream(new File("output. txt")); Cipher. Output. Stream cout. File = new Cipher. Output. Stream(out. File, cipher); length = encrypt. In. File. read(block); while(length!=-1){ cout. File. write(block, 0, length); length = encrypt. In. File. read(block); } cout. File. close(); encrypt. In. File. close(); out. File. close();

키쌍의 생성 40 java. security. Key. Pair. Generator를 이용 � � � 생성된 키는

키쌍의 생성 40 java. security. Key. Pair. Generator를 이용 � � � 생성된 키는 java. security. Key. Pair에 유지한다. 생성된 공개키 쌍은 get. Public(), get. Private() 메소드를 이용하 여 접근할 수 있다. 공개키와 개인키는 java. security. Public. Key, java. security. Private. Key 객체로 유지할 수 있다. Key. Pair. Generator kpg = Key. Pair. Generator. get. Instance("RSA"); kpg. initialize(1024); Key. Pair key. Pair = kpg. gen. Key. Pair(); Public. Key pub. Key = key. Pair. get. Public(); Private. Key priv. Key = key. Pair. get. Private();

공개키/개인키의 파일 처리 42 Key. Pair. Generator kpg = Key. Pair. Generator. get. Instance("RSA");

공개키/개인키의 파일 처리 42 Key. Pair. Generator kpg = Key. Pair. Generator. get. Instance("RSA"); kpg. initialize(1024); Key. Pair key. Pair = kpg. gen. Key. Pair(); Public. Key pub. Key = key. Pair. get. Public(); Private. Key priv. Key = key. Pair. get. Private(); File. Output. Stream public. Fos = new File. Output. Stream(pub. Key. File); public. Fos. write(pub. Key. get. Encoded()); public. Fos. close(); File. Output. Stream private. Fos = new File. Output. Stream(priv. Key. File); private. Fos. write(priv. Key. get. Encoded()); private. Fos. close(); File. Input. Stream private. Fis = new File. Input. Stream(priv. Key. File); Byte. Array. Output. Stream priv. Key. Baos = new Byte. Array. Output. Stream(); int cur. Byte = 0; while((cur. Byte = private. Fis. read())!=-1){ priv. Key. Baos. write(cur. Byte); } PKCS 8 Encoded. Key. Spec key. Spec = new PKCS 8 Encoded. Key. Spec(priv. Key. Baos. to. Byte. Array()); priv. Key. Baos. close();

RSA 암호 예제 43 try{ Key. Pair. Generator kpg = Key. Pair. Generator. get.

RSA 암호 예제 43 try{ Key. Pair. Generator kpg = Key. Pair. Generator. get. Instance("RSA"); kpg. initialize(1024); Key. Pair key. Pair = kpg. gen. Key. Pair(); Public. Key pub. Key = key. Pair. get. Public(); Private. Key priv. Key = key. Pair. get. Private(); Cipher cipher = Cipher. get. Instance("RSA/ECB/PKCS 1 Padding"); cipher. init(Cipher. ENCRYPT_MODE, pub. Key); String plaintext = "This is a secret message!"; byte[] ciphertext = cipher. do. Final(plaintext. get. Bytes()); for(byte b: ciphertext) System. out. printf("%02 X ", b); System. out. println(); cipher. init(Cipher. DECRYPT_MODE, priv. Key); byte[] cleartext = cipher. do. Final(ciphertext); for(byte b: cleartext) System. out. print((char)b); System. out. println(); } catch(){ }

45 전자서명 생성 try{ … Signature signature. Engine = Signature. get. Instance("MD 5 with.

45 전자서명 생성 try{ … Signature signature. Engine = Signature. get. Instance("MD 5 with. RSA"); signature. Engine. init. Sign(priv. Key); String plaintext = "This is my message!"; signature. Engine. update(plaintext. get. Bytes()); byte[] signature = signature. Engine. sign(); for(byte b: signature) System. out. printf("%02 X ", b); } catch(){ }

46 전자서명 검증 try{ … Signature signature. Engine = Signature. get. Instance("MD 5 with.

46 전자서명 검증 try{ … Signature signature. Engine = Signature. get. Instance("MD 5 with. RSA"); String plaintext = "This is my message!"; signature. Engine. init. Verify(pub. Key); signature. Engine. update(plaintext. get. Bytes()); boolean is. Verified = signature. Engine. verify(signature); System. out. println(is. Verified); } catch(){ }

X. 500 DN 명명법 50 DN(Distinguished Name) 명명법: 계층구조 형태 사용 � � �

X. 500 DN 명명법 50 DN(Distinguished Name) 명명법: 계층구조 형태 사용 � � � C: Country (국가) O: Organization (소속기관) OU: Organizational unit (부서) CN: Common Name (이름) 예 C=KR, O=중부대학교, OU=정보보호학과, CN=이병천

3. 2 Bouncy. Castle 패키지 51 JCE는 인증서를 생성하는 방법을 제공하지 않는다. Bouncy. Castle

3. 2 Bouncy. Castle 패키지 51 JCE는 인증서를 생성하는 방법을 제공하지 않는다. Bouncy. Castle 패키지 이용 가능 � � org. bouncycastle. x 509. X 509 V 3 Certificate. Generator 엔진 제공 http: //www. bouncycastle. org/download/bcprov-jdk 15 on-149. jar 파일을 다운로드하여 Add External JARs로 등록하여 사용

인증기관 인증서 52 X 509 V 3 Certificate. Generator cert. Gen = new X

인증기관 인증서 52 X 509 V 3 Certificate. Generator cert. Gen = new X 509 V 3 Certificate. Generator(); cert. Gen. set. Serial. Number(Big. Integer. value. Of(System. current. Time. Millis())); cert. Gen. set. Issuer. DN(new X 500 Principal("C=KR, CN=Root")); cert. Gen. set. Subject. DN(new X 500 Principal("C=KR, CN=Root")); Gregorian. Calendar current. Date = new Gregorian. Calendar(); Gregorian. Calendar expired. Date = new Gregorian. Calendar(current. Date. get(Calendar. YEAR)+1, current. Date. get(Calendar. MONTH), current. Date. get(Calendar. DAY_OF_MONTH)); cert. Gen. set. Not. Before(current. Date. get. Time()); cert. Gen. set. Not. After(expired. Date. get. Time()); cert. Gen. set. Public. Key(pub. Key); cert. Gen. set. Signature. Algorithm("SHA 1 with. RSAEncryption"); cert. Gen. add. Extension(X 509 Extensions. Basic. Constraints, true, new Basic. Constraints(0)); cert. Gen. add. Extension(X 509 Extensions. Key. Usage, true, new Key. Usage(Key. Usage. digital. Signature | Key. Usage. key. Cert. Sign | Key. Usage. c. RLSign)); X 509 Certificate root. Cert = (X 509 Certificate)cert. Gen. generate(signature. Key, "BC");

일반 사용자 인증서 53 X 509 V 3 Certificate. Generator cert. Gen = new

일반 사용자 인증서 53 X 509 V 3 Certificate. Generator cert. Gen = new X 509 V 3 Certificate. Generator(); … cert. Gen. add. Extension(X 509 Extensions. Authority. Key. Identifier, false, new Authority. Key. Identifier. Structure(ca. Cert)); cert. Gen. add. Extension(X 509 Extensions. Subject. Key. Identifier, false, new Subject. Key. Identifier. Structure(pub. Key)); cert. Gen. add. Extension(X 509 Extensions. Key. Usage, true, new Key. Usage(Key. Usage. digital. Signature | Key. Usage. key. Encipherment)); X 509 Certificate alice. Cert = (X 509 Certificate)cert. Gen. generate(signature. Key, "BC");

인증서 저장 55 인증서 저장 File. Output. Stream fos = new File. Output. Stream(new

인증서 저장 55 인증서 저장 File. Output. Stream fos = new File. Output. Stream(new File("alice. Cert. der")); fos. write(alice. Cert. get. Encoded()); fos. close(); 저장된 인증서 불러오기 � java. security. cert. Certificate. Factory 엔진 이용 Certificate. Factory cf = Certificate. Factory. get. Instance("X. 509"); File. Input. Stream fis = new File. Input. Stream(new File("alice. Cert. der")); X 509 Certificate cert = (X 509 Certificate)cf. generate. Certificate(fis); fis. close();

개인키 저장 56 java. security. Key. Store 엔진 사용 � � Key. Store는 패스워드를

개인키 저장 56 java. security. Key. Store 엔진 사용 � � Key. Store는 패스워드를 이용하여 저장할 키를 보호함 개인키를 저장할 경우에는 인증경로를 제공해야 함 인증경로 배열은 계층구조 트리에서 아래부터 위쪽으로 만듬 개인키를 식별하기 위한 정보 Alias 정보 이용 “Alice. Private. Key. Alias” char[] code = {'s', 'e', 'c', 'r', 'e', 't', 'c', 'o', 'd', 'e'}; Key. Store ks = Key. Store. get. Instance(Key. Store. get. Default. Type()); ks. load(null, null); X 509 Certificate[] chain = new X 509 Certificate[3]; chain[0] = alice. Cert; chain[0] = inter. Cert; chain[1] = root. Cert; ks. set. Key. Entry("Alice. Private. Key. Alias", alice. Priv. Key, code, chain); File. Output. Stream fos = new File. Output. Stream(new File("alice. Priv. key")); ks. store(fos, code); fos. close();

인증서 폐지 목록 58 Bouncy. Castle � org. bouncycastle. x 509. X 509 V

인증서 폐지 목록 58 Bouncy. Castle � org. bouncycastle. x 509. X 509 V 2 CRLGenerator 엔진 이용 X 509 V 2 CRLGenerator crl. Gen = new X 509 V 2 CRLGenerator(); crl. Gen. set. Issuer. DN(ca. Cert. get. Subject. X 500 Principal()); Gregorian. Calendar current. Date = new Gregorian. Calendar(); Gregorian. Calendar next. Date = new Gregorian. Calendar(current. Date. get(Calendar. YEAR)+1, (current. Date. get(Calendar. MONTH)+1)%12, current. Date. get(Calendar. DAY_OF_MONTH)); crl. Gen. set. This. Update(current. Date. get. Time()); crl. Gen. set. Next. Update(next. Date. get. Time()); crl. Gen. set. Signature. Algorithm("SHA 1 with. RSAEncryption"); crl. Gen. add. CRLEntry(revoke. Cert. get. Serial. Number(), current. Date. get. Time(), CRLReason. superseded); X 509 CRL crl = crl. Gen. generate(signature. Key, "BC");

인증서 폐지 여부 확인 60 crl이 Bob의 인증서가 폐지될 경우에 이 정보를 유지하는 crl이라

인증서 폐지 여부 확인 60 crl이 Bob의 인증서가 폐지될 경우에 이 정보를 유지하는 crl이라 하자. get. Revoked. Certificate() 메소드를 호출하여 이 값이 null이 면 해당 인증서는 폐지되지 않았다는 것을 의미한다. 폐지된 경우 get. Certificate. Issuer() 메소드를 통해 폐지된 인증서의 발급자 정보 를 획득할 수 있다. 이 때 이 값이 null이면 CRL 발급자가 인증서의 발급자라는 것을 나타낸다. X 509 Entry entry = crl. get. Revoked. Certificate(bob. Cert. get. Serial. Number()); if(entry!=null){ System. out. printf("인증서번호: %d%n", entry. get. Serial. Number()); if(entry. get. Certificate. Issuer()==null) System. out. printf("발급자: %s%n", crl. get. Issuer. X 500 Principal()); else System. out. printf("발급자: %s%n", entry. get. Certificate. Issuer()); }

인증서 폐지 목록의 저장 및 활용 61 CRL 저장 File. Output. Stream fos =

인증서 폐지 목록의 저장 및 활용 61 CRL 저장 File. Output. Stream fos = new File. Output. Stream(new File("normal. crl")); fos. write(crl. get. Encoded()); fos. close(); 저장된 CRL 불러오기 Certificate. Factory cf = Certificate. Factory. get. Instance("X. 509"); File. Input. Stream fis = new File. Input. Stream(new File(“normal. crl")); X 509 CRL crl = (X 509 CRL)cf. generate. CRL(fis); fis. close();

인증서 디렉토리 62 java. security. cert. Cert. Store를 이용하여 생성할 수 있음 List list

인증서 디렉토리 62 java. security. cert. Cert. Store를 이용하여 생성할 수 있음 List list = new Array. List(); list. add(root. Cert); list. add(inter. Cert); list. add(alice. Cert); list. add(bob. Cert); list. add(root. CRL); list. add(inter. CRL); Collection. Cert. Store. Parameters params = new Collection. Cert. Store. Parameters(list); Cert. Store store = Cert. Store. get. Instance("Collection", params);

인증 경로 63 java. security. cert. Cert. Path를 이용하여 인증경로 생성 java. security. Cert.

인증 경로 63 java. security. cert. Cert. Path를 이용하여 인증경로 생성 java. security. Cert. Path. Validator를 이용하여 인증 경로 를 유효성을 검증 Certificate. Factory cf = Certificate. Factory. get. Instance("X. 509"); List<Certificate> cert. Chain = new Array. List(); cert. Chain. add(bob. Cert); cert. Chain. add(inter. Cert); Cert. Path cert. Path = cf. generate. Cert. Path(cert. Chain); Set trust = Collections. singleton(new Trust. Anchor(root. Cert, null)); Cert. Path. Validator validator = Cert. Path. Validator. get. Instance("PKIX", "BC"); PKIXParameters param = new PKIXParameters(trust); param. add. Cert. Store(store); param. set. Date(new Date()); try{ PKIXCert. Path. Validator. Result result = (PKIXCert. Path. Validator. Result)validator. validate(cert. Path, param); } catch(Cert. Path. Validator. Exception e){ System. out. println("validation failed "+e. get. Index()+" detail: "+e. get. Message()); }