자바 암호화 프로그래밍 전자상거래보안.

Slides:



Advertisements
Similar presentations
3. 메소드와 변수 SCJP 자격증 프로젝트 발표자 : 최선웅. 1. 메 소 드 개 념 2. 메 소 드 양 식 3. 메 소 드 변 수 4. 메 소 드 예 제 5. 참 고 문 헌 / 자 료 목 차.
Advertisements

1. 브라우저에서 로 관리창으로 접속해서, 서버 인증서를 설치 할 서버를 선택하고 Manage 버튼을 클릭합니다. 2. Security 탭을 선택한 후, 인증서 Trust.
HTTPS Packet Capture Tutorial
목 차 C# 언어 특징 .NET 프레임워크 C# 콘솔 프로그램 C# 윈도우 프로그램 실습 프로그래밍세미나 2.
목차 Contents 무선인터넷용 비밀번호 설정방법 Windows 7 Windows 8 Windows XP MAC OS.
Chapter 16 : Struts 프레임워크 2. chapter 16 : Struts 프레임워크 2.
10. 예외 처리.
클래스 class, 객체 object 생성자 constructor 접근 access 제어 이벤트 event 처리.
자바 암호 프로그래밍 Java Cryptography Programming
최윤정 Java 프로그래밍 클래스 상속 최윤정
Ch.07-5 xml-rpc 사용하기 김상엽.
자바 암호 프로그래밍 Java Cryptography Programming
컴퓨터 프로그래밍 기초 [Final] 기말고사
자바 암호 프로그래밍 Java Cryptography Programming
자바 암호 프로그래밍 Java Cryptography Programming
자바 암호 프로그래밍 Java Cryptography Programming
Chapter 3. Architecture AI & HCI Lab 김 주 영.
7장 배열 ②.
자바 암호 프로그래밍 Java Cryptography Programming
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
Lesson 5. 레퍼런스 데이터형.
자바 암호 프로그래밍 Java Cryptography Programming
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
8.1 인터페이스 개요와 인터페이스 정의 8.2 인터페이스의 사용 8.3 인터페이스의 상속 8.4 인터페이스 참조
교과목 소개 정보보호.
암호학 응용 Applied cryptography
Lesson 9. 예외처리.
Lesson 6. 형변환.
SSL (Secure Sockets Layers Protocol)
5장. 참조 타입.
제 1장 소 개 컴퓨터네트워크실험실 우 준.
File Depender 중간 발표.
공개키 암호화 프로그래밍 전자상거래보안.
CHAPTER 02 OpenCV 개요 PART 01 영상 처리 개요 및 OpenCV 소개.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
패키지와 접근 제어 패키지에 대하여 접근 제어에 대하여.
2 : 대칭암호화 소제목 : 기본적인 대칭암호화.
자바 5.0 프로그래밍.
자바 암호 프로그래밍 Java Cryptography Programming
Method & library.
인터넷응용프로그래밍 JavaScript(Intro).
Lesson 4. 수식과 연산자.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
웹어플리케이션보안 암호프로그래밍, crypto-js
자바스크립트 암호 프로그래밍 Javascript Cryptography Programming
HTTP 프로토콜의 요청과 응답 동작을 이해한다. 서블릿 및 JSP 를 알아보고 역할을 이해한다.
전자서명의 형태 수기서명 디지털서명. 전자서명의 형태 수기서명 디지털서명 전자서명의 필요성.
Lesson 2. 기본 데이터형.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
15장 컬렉션 프레임워크 Section 1 컬렉션 프레임워크의 개요 Section 2 리스트 Section 3 셋
Power Java 제11장 상속.
JA A V W. 06.
비대칭 암호화 알고리즘 공개키 암호화 알고리즘 소속 : 한세사이버보안고등학교 조장 : 안도현
VHDL를 이용한 DES 설계 정보통신컴퓨터공학부 5조 김인옥, 백미숙
객체기반 SW설계 팀활동지 4.
데이터 동적 할당 Collection class.
암호학 응용 Applied cryptography
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
발표자 : 이지연 Programming Systems Lab.
Numerical Analysis Programming using NRs
(c) Byoungcheon Lee, Joongbu Univ.
2.가상머신의 탐험 도구, Oolong에 대하여 ps lab 김윤경.
JSP Programming with a Workbook
자바 암호 프로그래밍 Java Cryptography Programming
암호 시스템 (Crypto system) 신효철
Exporting User Certificate from Internet Explorer
7 생성자 함수.
6 객체.
자바 암호 프로그래밍 Java Cryptography Programming
Presentation transcript:

자바 암호화 프로그래밍 전자상거래보안

차례 1. JCA/JCE 소개 2. 의사난수 생성 3. 대칭키 암호 4. 해쉬함수 5. MAC 6. 공개키 암호 7. 전자서명 8. 인증서 9. 파일 암호화/복호화

1. JCA/JCE 소개 자바에서의 암호 구현 JCA(Java Cryptography Architecture) Import java.security.* JCE(Java Cryptography Extension) Import javax.crypto.* JCA와 JCE는 프로그래머들이 응용을 개발할 때 사용할 수 있는 추상 계층(abstraction layer)을 제공하여 준다.

JCA JCA는 제공자 기반 구조(provider-based architecture) 라 하며,다음과 같은 원리를 기반으로 설계되었다. 알고리즘 독립성 알고리즘 확장성: 새 알고리즘을 쉽게 추가할 수 있는 구조라는 것을 말한다. 구현 독립성: 프로그래머는 알고리즘을 구현한 제공자가 누구인 지 알 필요가 없다. 구현간 상호운영: 프로그래머가 서로 다른 제공자에 의해 제공되 는 구현을 사용하더라도 동작해야 한다는 것을 말한다.

알고리즘의 독립성 같은 종류의 여러 알고리즘을 동일한 메소드를 이용하여 암 호연산을 수행할 수 있음. 이를 위해 다음과 같이 암호연산을 분류한다. MessageDigest: 해쉬함수 Signature: 전자서명 KeyPairGenerator: 전자서명을 위한 키 쌍 생성 KeyFactory KeyStore: 다양한 암호키 관리 SecureRandom: 의사난수 비트 생성 AlgorithmParameters AlgorithmParameterGenerator CertificateFactory: 인증서와 인증서폐지목록을 생성 CertPathBuilder CertStore

알고리즘의 독립성 같은 인터페이스에 알고리즘 이름만 바꾸어 사용할 수 있도록 구현 try{ 같은 인터페이스에 알고리즘 이름만 바꾸어 사용할 수 있도록 구현 try{ MessageDigest md5 = MessageDigest.getInstance(“MD5”); // MessageDigest md5 = MessageDigest.getInstance(“SHA-1”); md5.update(buffer); byte[] digest = md5.digest(); for(int i=0; i<digest.length; i++) System.out.printf(“%02X ”, digest[i]); } catch(NoSuchAlgorithmException e){ e.printStackTrace();

JCE JCE는 JCA를 확장한 것으로, 다음과 같은 엔진을 추가 로 제공한다. Cipher: 암호화/복호화 KeyGenerator: Cipher를 위한 비밀키 생성 SecretKeyFactory KeyAgreement: 키 동의 프로토콜을 위한 클래스 Mac: 메시지 인증 코드 JCE의 엔진은 javax.crypto 패키지에 포함되어 있다. JDK 1.4부터 JCA/JCE 모두 기본적으로 포함되어 있다.

2. 의사난수 생성 자바에서 난수는 보통 java.lang.Math에 정의된 random() 메소드나 java.util.Random 클래스를 사용한 다. 하지만 이들은 암호학적으로 안전하지 못하다. JCA에서는 java.security.SecureRandom 엔진을 사용한 다. 이 엔진은 java.util.Random 클래스를 상속받고 있어, nextInt() 와 같은 매우 편리한 메소드들을 제공하고 있다. 의사난수 비트 생성은 보통 실제 랜덤한 seed를 사용한 다. 이를 위해 사용자가 직접 setSeed 메소드를 사용할 수 있지만 일반적으로는 엔진이 안전한 seed를 자동으 로 선택하도록 하는 것이 바람직하다.

의사난수 생성 사례 try{ SecureRandom csprng = SecureRandom.getInstance("SHA1PRNG"); boolean randBool = csprng.nextBoolean(); int randInt = csprng.nextInt(); byte[] randBytes = new byte[3]; csprng.nextBytes(randomBytes); } catch(NoSuchAlgorithmException e){ e.printStackTrace();

3. 대칭키 암호 비밀키 생성 Key Spec 변환 채우기 암호화 모드 Cipher 객체의 선언 및 초기화 암호화/복호화

비밀키의 생성 비밀키는 알고리즘에 따라 키 길이가 다르다. 자바에서는 사용자가 키 길이를 별도로 제시하지 않아 도 선택한 알고리즘에 필요한 비밀키를 생성하여 준다. 필요하면 특정한 알고리즘을 사용하여 키를 생성하도록 설정할 수도 있다. (init 메소드 이용) init(int keySize) init(SecureRandom random) init(int keySize, SecureRandom random) javax.crypto.KeyGenerator 엔진을 사용 KeyGenerator kg = KeyGenerator.getInstance("AES"); 키의 실제 생성은 generateKey 메소드를 이용하며, 그 결과는 SecretKey 클래스에 유지된다.

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

채우기 암호화 모드 블록 암호 방식에서는 마지막 블록을 완전 블록으로 만들기 위해 채우기가 필요하다. JCE는 4가지 채우기 방법을 제공 none: 사용자가 완전 블록임을 보장해 주어야 한다. PKCS5Padding SSL3Padding (예약만 되어 있고, 실제 구현되어 있지 않음) OAEPWith<digest>And<mgf>Padding 암호화 모드 ECB, CBC, CFB, CTR 모드 제공

암호화/복호화 Cipher 엔진 Cipher 엔진은 비밀키 방식의 암호화/복호화를 하기 위해 사용 된다. 이 엔진을 사용하기 위해서는 먼저 사용할 알고리즘을 지정하여 야 한다. 이 때 알고리즘 이름 뿐만 아니라 암호화 모드, 채우기 방식을 함 께 지정할 수 있다. 암호화 모드와 채우기 방식을 지정하지 않으면 제공자에 의해 결 정된 모드와 채우기 방식으로 암호화가 이루어진다. Cipher DESCipher = Cipher.getInstance("DES"); Cipher DESCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

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

암호화 방법1. doFinal() 메소드만 호출 암호화하고자 하는 평문의 크기가 작을 경우 방법2.일련의 update() 메소드를 호출한 후에 doFinal() 메소드 호출 암호화하고자 하는 평문의 크기가 크거나 나누어져 있을 경우 String plaintext = "This is a secret message!"; byte[] ciphertext = cipher.doFinal(plaintext.getBytes()); byte[] ciphertext = new byte[cipher.getOutputSize(input.length)]; int ctLength = cipher.update(myByteArray01, 0, myByteArray01.length, ciphertext, 0); ctLength += cipher.update(myByteArray02, 0, myByteArray02.length, ciphertext, ctLength); ctLength += cipher.doFinal(ciphertext, ctLength);

DES 암호화 종합 예제 try{ KeyGenerator kg = KeyGenerator.getInstance("DES"); SecretKey key = kg.generateKey(); SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "DES"); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec); String plaintext = "This is a secret message!"; byte[] ciphertext = cipher.doFinal(plaintext.getBytes()); for(int i=0; i<ciphertext.length; i++){ System.out.printf("%02X ", ciphertext[i]); } System.out.println(); cipher.init(Cipher.DECRYPT_MODE,keySpec); byte[] cleartext = cipher.doFinal(ciphertext); for(int i=0; i<cleartext.length; i++){ System.out.print((char)cleartext[i]); catch(){

4. 해쉬함수 해쉬함수란? 해쉬함수의 요구조건 입력값에 대한 고정된 길이의 특징값을 출력하는 함수. 암호키를 사용하지 않는 공개된 함수 해쉬함수의 요구조건 일방향성 충돌회피성

해쉬함수 기본적으로 지원하는 해쉬함수들 해쉬값의 비교 MD2 (RFC 1319) MD5 (RFC 1321) SHA-1 (NIST FIPS 180-1) SHA-256, SHA-384, SHA-512: SHA-1의 해쉬값의 길이를 증가 시켜 충돌회피성을 높이고자 제안된 해쉬함수 해쉬값의 비교 isEqual 메소드 이용: 두 개의 바이트 배열을 비교한다. java.util.Array.equals()을 이용할 수도 있다.

해쉬함수 java.security.MessageDigest 엔진을 사용 try{ MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(plaintext.getBytes()); byte[] digest01 = md5.digest(); for(byte b: digest01) System.out.printf("%02X ", b); System.out.println(); byte[] digest02 = md5.digest(); System.out.printf("Verified = %s%n", MessageDigest.isEqual(digest01, digest02)); } catch(NoSuchAlgorithmException e){ e.printStackTrace();

두 메시지의 해쉬값 비교 public class DigestTest { public static void main(String[] args) { String plaintext01 = "This is a simple message."; String plaintext02 = "This is a simple message"; try{ MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(plaintext01.getBytes()); byte[] digest01 = md5.digest(); for(byte b: digest01) System.out.printf("%02X ", b); System.out.println(); md5.update(plaintext02.getBytes()); byte[] digest02 = md5.digest(); for(byte b: digest02) System.out.printf("%02X ", b); System.out.printf("Verified = %s%n", MessageDigest.isEqual(digest01, digest02)); } catch(NoSuchAlgorithmException e){ e.printStackTrace(); } // main } // DigestTest

5. MAC MAC(메시지인증코드)란? 기본적으로 제공되는 MAC 알고리즘 해쉬함수와 공유된 대칭키를 이용하여 송수신하는 메시지를 인 증하는데 사용 해쉬함수 기반의 MAC은 javax.crypto.Mac 엔진을 사용 MAC은 대칭 암호알고리즘처럼 암호키가 필요하다. 자바 라이브러리에서는 기존 대칭키를 MAC에 적합하도록 변환 하여 사용한다. 기본적으로 제공되는 MAC 알고리즘 HmacMD5, HmacSHA1, HmacSHA256, HmacSHA384, HmacSHA512

MAC 사례 try{ KeyGenerator kg = KeyGenerator.getInstance("AES"); SecretKey key = kg.generateKey(); SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(keySpec); mac.update(plaintext.getBytes()); byte[] digest01 = mac.doFinal(); for(byte b: digest01) System.out.printf("%02X ", b); System.out.println(); byte[] digest02 = mac.doFinal(); System.out.printf("Verified = %s%n", MessageDigest.isEqual(digest01, digest02)); } catch(NoSuchAlgorithmException e){ e.printStackTrace();

6. 공개키 암호 키쌍의 생성 키의 인코딩 공개키/개인키의 파일 처리 RSA 암호

키쌍의 생성 java.security.KeyPairGenerator를 이용 생성된 공개키 쌍은 getPublic(), getPrivate() 메소드를 이용하 여 접근할 수 있다. 공개키와 개인키는 java.security.PublicKey, java.security.PrivateKey 객체로 유지할 수 있다. KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); KeyPair keyPair = kpg.genKeyPair(); PublicKey pubKey = keyPair.getPublic(); PrivateKey privKey = keyPair.getPrivate();

키의 인코딩 대칭키는 특별한 인코딩을 사용하지 않지만 공개키들은 특별한 인코딩을 사용한다. 이와 같은 인코딩이 필요한 이유는 유지해야 하는 정보가 복잡하기 때문이다. RSA의 경우에는 개인키/공개키가 두 개의 정수로 구성 공개키: (n,e) 개인키: (n,d) RSA 알고리즘의 경우 공개키는 X.509 인코딩을 사용. 공개키는 인증서와 함께 파일시 스템에 저장 개인키는 PKCS8 인코딩을 사용. 개인키는 패스워드 기반 암호방 식을 통해 암호화된 상태로 저장

공개키/개인키의 파일 처리 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); KeyPair keyPair = kpg.genKeyPair(); PublicKey pubKey = keyPair.getPublic(); PrivateKey privKey = keyPair.getPrivate(); FileOutputStream publicFos = new FileOutputStream(pubKeyFile); publicFos.write(pubKey.getEncoded()); publicFos.close(); FileOutputStream privateFos = new FileOutputStream(privKeyFile); privateFos.write(privKey.getEncoded()); privateFos.close(); FileInputStream privateFis = new FileInputStream(privKeyFile); ByteArrayOutputStream privKeyBaos = new ByteArrayOutputStream(); int curByte = 0; while((curByte = privateFis.read())!=-1){ privKeyBaos.write(curByte); } PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyBaos.toByteArray()); privKeyBaos.close();

RSA 암호 예제 try{ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); KeyPair keyPair = kpg.genKeyPair(); PublicKey pubKey = keyPair.getPublic(); PrivateKey privKey = keyPair.getPrivate(); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); String plaintext = "This is a secret message!"; byte[] ciphertext = cipher.doFinal(plaintext.getBytes()); for(byte b: ciphertext) System.out.printf("%02X ", b); System.out.println(); cipher.init(Cipher.DECRYPT_MODE, privKey); byte[] cleartext = cipher.doFinal(ciphertext); for(byte b: cleartext) System.out.print((char)b); } catch(){

7. 전자서명 전자문서에 대한 공개키 암호기술을 이용한 서명 java.security.Signature 엔진을 사용 기본적으로 제공되는 전자서명 알고리즘 ECDSA, MD2withRSA, MD5withRSA, NONEwithDSA, SHA1withDSA, SHA1withRSA

전자서명 생성 try{ … Signature signatureEngine = Signature.getInstance("MD5withRSA"); signatureEngine.initSign(privKey); String plaintext = "This is my message!"; signatureEngine.update(plaintext.getBytes()); byte[] signature = signatureEngine.sign(); for(byte b: signature) System.out.printf("%02X ", b); } catch(){

전자서명 검증 try{ … Signature signatureEngine = Signature.getInstance("MD5withRSA"); String plaintext = "This is my message!"; signatureEngine.initVerify(pubKey); signatureEngine.update(plaintext.getBytes()); boolean isVerified = signatureEngine.verify(signature); System.out.println(isVerified); } catch(){

8. 인증서 인증서의 구성

인증서의 확장 필드 발급자키식별자(Authority Key Identifier): 이 인증서를 확인할 때 사용할 발급자의 공개키를 독특하게 식별하는 식별자 자체 서명 인증서를 제외한 모든 인증서의 필수 요소 주체키식별자(Subject Key Identifier): 이 인증서에 포함된 공개키 를 독특하게 식별하는 식별자 인증기관 인증서의 경우에는 필수 요소 키용도(Key Usage): 이 인증서의 바인딩되어 있는 공개키의 사용용 도를 한정하기 위해 사용 전자서명, 부인방지, 키 암호화, 데이터 암호화, 키 동의 등 인증기관의 경우 keyCertSign, cRLSign이 설정되어 있어함 CRL 분배점(CRL distribution point): 이 인증서의 폐지 여부를 확 인하기 위한 인증서 폐지 목록이 있는 위치 Basic-Constraints: 이 인증서가 인증기관의 인증서임을 나타내기 위해 사용됨

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

인증서 생성하기 JCE는 인증서를 생성하는 방법을 제공하지 않는다. BouncyCastle 패키지 이용 가능 org.bouncycastle.x509.X509V3CertificateGenerator 엔진 제 공 http://www.bouncycastle.org/download/bcprov-jdk15on-149.jar 파일을 다운로드하여 Add External JARs로 등록하여 사용

인증기관 인증서 X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); certGen.setIssuerDN(new X500Principal("C=KR,CN=Root")); certGen.setSubjectDN(new X500Principal("C=KR,CN=Root")); GregorianCalendar currentDate = new GregorianCalendar(); GregorianCalendar expiredDate = new GregorianCalendar(currentDate.get(Calendar.YEAR)+1, currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DAY_OF_MONTH)); certGen.setNotBefore(currentDate.getTime()); certGen.setNotAfter(expiredDate.getTime()); certGen.setPublicKey(pubKey); certGen.setSignatureAlgorithm("SHA1withRSAEncryption"); certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(0)); certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign)); X509Certificate rootCert = (X509Certificate)certGen.generate(signatureKey,"BC");

일반 사용자 인증서 X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); … certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert)); certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey)); certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment)); X509Certificate aliceCert = (X509Certificate)certGen.generate(signatureKey,"BC");

인증서 검증 인증서의 서명 확인 인증서의 유효기간 확인 인증서의 사용 용도 확인 인증서의 폐지 여부 확인 void verify(PublicKey key) 문제가 있으면 각 종 예외 발생 인증서의 유효기간 확인 void checkValidity() 인증서의 사용 용도 확인 인증서의 폐지 여부 확인

인증서 저장 인증서 저장 저장된 인증서 불러오기 java.security.cert.CertificateFactory 엔진 이용 FileOutputStream fos = new FileOutputStream(new File("aliceCert.der")); fos.write(aliceCert.getEncoded()); fos.close(); CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream fis = new FileInputStream(new File("aliceCert.der")); X509Certificate cert = (X509Certificate)cf.generateCertificate(fis); fis.close();

개인키 저장 java.security.KeyStore 엔진 사용 KeyStore는 패스워드를 이용하여 저장할 키를 보호함 개인키를 저장할 경우에는 인증경로를 제공해야 함 인증경로 배열은 계층구조 트리에서 아래부터 위쪽으로 만듬 개인키를 식별하기 위한 정보 Alias 정보 이용 “AlicePrivateKeyAlias” char[] code = {'s','e','c','r','e','t','c','o','d','e'}; KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(null,null); X509Certificate[] chain = new X509Certificate[3]; chain[0] = aliceCert; chain[0] = interCert; chain[1] = rootCert; ks.setKeyEntry("AlicePrivateKeyAlias",alicePrivKey,code,chain); FileOutputStream fos = new FileOutputStream(new File("alicePriv.key")); ks.store(fos,code); fos.close();

인증서 폐지 목록

인증서 폐지 목록 BouncyCastle org.bouncycastle.x509.X509V2CRLGenerator 엔진 이용 X509V2CRLGenerator crlGen = new X509V2CRLGenerator(); crlGen.setIssuerDN(caCert.getSubjectX500Principal()); GregorianCalendar currentDate = new GregorianCalendar(); GregorianCalendar nextDate = new GregorianCalendar(currentDate.get(Calendar.YEAR)+1, (currentDate.get(Calendar.MONTH)+1)%12, currentDate.get(Calendar.DAY_OF_MONTH)); crlGen.setThisUpdate(currentDate.getTime()); crlGen.setNextUpdate(nextDate.getTime()); crlGen.setSignatureAlgorithm("SHA1withRSAEncryption"); crlGen.addCRLEntry(revokeCert.getSerialNumber(), currentDate.getTime(), CRLReason.superseded); X509CRL crl = crlGen.generate(signatureKey,"BC");

인증서 폐지 목록 인증서 폐지 사유

인증서 폐지 여부 확인 crl이 Bob의 인증서가 폐지될 경우에 이 정보를 유지하는 crl이라 하자. getRevokedCertificate() 메소드를 호출하여 이 값이 null이 면 해당 인증서는 폐지되지 않았다는 것을 의미한다. 폐지된 경우 getCertificateIssuer() 메소드를 통해 폐지된 인증서의 발급자 정보 를 획득할 수 있다. 이 때 이 값이 null이면 CRL 발급자가 인증서의 발급자라는 것을 나타낸다. X509Entry entry = crl.getRevokedCertificate(bobCert.getSerialNumber()); if(entry!=null){ System.out.printf("인증서번호: %d%n", entry.getSerialNumber()); if(entry.getCertificateIssuer()==null) System.out.printf("발급자: %s%n", crl.getIssuerX500Principal()); else System.out.printf("발급자: %s%n", entry.getCertificateIssuer()); }

인증서 폐지 목록의 저장 및 활용 CRL 저장 저장된 CRL 불러오기 FileOutputStream fos = new FileOutputStream(new File("normal.crl")); fos.write(crl.getEncoded()); fos.close(); CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream fis = new FileInputStream(new File(“normal.crl")); X509CRL crl = (X509CRL)cf.generateCRL(fis); fis.close();

인증서 디렉토리 java.security.cert.CertStore를 이용하여 생성할 수 있음 List list = new ArrayList(); list.add(rootCert); list.add(interCert); list.add(aliceCert); list.add(bobCert); list.add(rootCRL); list.add(interCRL); CollectionCertStoreParameters params = new CollectionCertStoreParameters(list); CertStore store = CertStore.getInstance("Collection",params);

인증 경로 java.security.cert.CertPath를 이용하여 인증경로 생성 java.security.CertPathValidator를 이용하여 인증 경로 를 유효성을 검증 CertificateFactory cf = CertificateFactory.getInstance("X.509"); List<Certificate> certChain = new ArrayList(); certChain.add(bobCert); certChain.add(interCert); CertPath certPath = cf.generateCertPath(certChain); Set trust = Collections.singleton(new TrustAnchor(rootCert,null)); CertPathValidator validator = CertPathValidator.getInstance("PKIX","BC"); PKIXParameters param = new PKIXParameters(trust); param.addCertStore(store); param.setDate(new Date()); try{ PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(certPath,param); } catch(CertPathValidatorException e){ System.out.println("validation failed "+e.getIndex()+" detail: "+e.getMessage());

9. 파일 암호화/복호화 파일을 암호화: CipherInputStream 이용 파일은 FileInputStream 이용하여 입력 암호는 Cipher 객체로 입력

파일 암호화 FileInputStream inFile = new FileInputStream(new File("input.txt")); KeyGenerator kg = KeyGenerator.getInstance("AES"); SecretKey key = kg.generateKey(); SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec); final int BLOCKSIZE = cipher.getBlockSize(); CipherInputStream cinFile = new CipherInputStream(inFile,cipher); FileOutputStream encryptOutFile = new FileOutputStream(new File("output")); byte[] block = new byte[BLOCKSIZE]; int length = cinFile.read(block); while(length!=-1){ encryptOutFile.write(block,0,length); length = cinFile.read(block); } encryptOutFile.close(); inFile.close(); cinFile.close();

파일 복호화 암호화된 파일을 복호화 : CipherOutputStream 이용 cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, keySpec); FileInputStream encryptInFile = new FileInputStream(new File("output")); FileOutputStream outFile = new FileOutputStream(new File("output.txt")); CipherOutputStream coutFile = new CipherOutputStream(outFile,cipher); length = encryptInFile.read(block); while(length!=-1){ coutFile.write(block,0,length); } coutFile.close(); encryptInFile.close(); outFile.close();