IT/Security2017. 2. 9. 18:59

 


이 글에서는 자바 암호 패키지인 JCA(Java Cryptography Architecture)와 JCE(Java Cryptography Extension)에 대해서 알아보고, 실무 활용 방법에 대해서 알아보겠습니다.


 

 

안녕하세요. IT반장입니다.

최근에 많은 프로그램들이 자바 언어로 만들어지고 있습니다. 서버 프로그램뿐 만 아니라 클라이언트 프로그램도 자바 언어로 프로그래밍 되는 경우가 많습니다. (예, 스프링프레임워크, 안드로이드 등) 그리고 자바 언어에서는 암호화를 위해 JCA(Java Cryptography Architecture)와 JCE(Java Cryptography Extension) 패키지를 제공하고 있습니다. 이 글에서는 암호 프로그래밍에서 쉽게 자주 접하게 되는 JCA와 JCE에 대해서 알아보고 실무 활용 방법을 설명하겠습니다.


 

 

1. JCA(Java Cryptography Architecture) [1][2]

 

  • 소개

  • JCA는 자바 프로그래밍 언어의 암호화를 위한 프레임워크입니다. JDK1.1 java.security 패키지에 처음 소개되었습니다.
  • 'Provider"-based architecture'를 사용하고 암호화, 키 생성 및 관리, 'secure random number' 생성, 인증서 검증 등의 API를 포함하고 있습니다.
  • JCA는 구현 독립성/호환성, 알고리즘 확장성을 고려하여 설계되었습니다.
    • 구현 독립성: 보안 기능별 독립된 제공자(provider)로 프로그래밍
    • 구현 호환성: 프로그램들간 추상화된(고정되지 않은) 제공자를 통해서 호환
    • 알고리즘 확장성: 대부분의 알고리즘을 지원하고, 임의의 제공자(provider) 추가 가능
  • JDK 1.4 이상에서는 JCE(Java Cryptography Extention)도 기본 포함됩니다.
  • 관련 암호 서비스를 정의하고 지원하기 위한 'Provider Framework'(java.security, javax.crypto, javax.crypto.spec, javax.crypto.interfaces 패키지)와 'Provider'(실제 암호 구현 내용이 포함된 Sun, SunRsaSign, SunJCE 패키지)를 제공합니다.

 

[참고] 기타 JDK 암호 라이브러리

  • JSSE(Java Secure Socket Extension): SSL/TLS 기능 제공
  • JGSS(Java Generic Security Services): Kerberos, 네트워크 보안 기능 제공
  • SASL(Simple Authentication and Security Layer): 네트워크 보안 기능 제공

 

  • 구조


[그림0] MD5 메시지 다이제스트 구현 설명도

[그림0]에서 보듯이 각각의 어플리케이션은 'Provider Framework'를 통해서 각각의 독립적인 'Provider'에 접근해서 암호 기능을 구현할 수 있습니다.

 

  • 키 관리
    • 키와 인증서들의 저장소를 관리하는 'keystore'가 있습니다.
    • java.security.KeyStore 클래스
    • .jks 파일 형태로 구현됨(또는 3DES로 암호화된 .jceks)
    • 어플리케이션은 각각의 'Provider'로부터 개별적인 keystore 구현 가능

       

  • 주요 클래스

클래스명(인터페이스명)

내용

Provider 

기본 Provider 클래스

Security 

Provider' 및 'security property' 관리

SecureRandom 

난수(random number) 생성

MessageDigest 

해시값 생성

Signature 

전자 서명 & 검증

Cipher

블록 암호(AES, DES, DESede, Blowfish, IDEA 등), 스트림 암호(RC4 등), 비대칭 암호(RSA 등), 패스워드 암호 (PBE 등) 등 제공

MAC

(Message Authentication Codes) 

MAC(해시값 생성 & 무결성 보장 기능)

Key(Key)  

기본 키 클래스(인터페이스)

KeyFactory 

키 타입 변환

SecretKeyFactory 

대칭키 타입 변환

KeyPairGenerator 

공개키/개인키 생성

KeyGenerator 

대칭키 생성

KeyAgreement 

키 교환 정보

KeyStore 

키 관리

AlgorithmParameters 

알고리즘 파라미터

AlgorithmParameterGenerator  

알고리즘 파라미터 생성

CertificateFactory 

인증서, 인증서폐기목록(CRL) 생성

CertPathBuilder 

인증서체인 생성

CertPathValidator 

인증서체인 검증

CertStore 

인증서, 인증서폐기목록(CRL) 관리

[표1] JCA 주요 클래스

 

  • 전자서명


[그림1] 전자서명 및 검증 설명도

 

  1. /* 키생성을 위한 KeyPairGenerator 클래스 생성 */  
  2. KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");  
  3.  
  4. /* 랜덤값 생성 */
  5. SecureRandom random = SecureRandom.getInstance("SHA1PRNG""SUN");  
  6. keyGen.initialize(1024, random);  
  7.  
  8. /* KeyPair 생성 */
  9. KeyPair pair = keyGen.generateKeyPair();  
  10.     
  11. /* 'SHA1withDSA' Signature 클래스 생성 */
  12. Signature dsa = Signature.getInstance("SHA1withDSA");  
  13.     
  14. /* 개인키 생성 */
  15. PrivateKey priv = pair.getPrivate();  
  16. dsa.initSign(priv);  
  17.     
  18. /* 데이터를 넣고, 전자서명 */  
  19. dsa.update(data);  
  20. byte[] sig = dsa.sign();  
  21.     
  22. /* 공개키 생성 */  
  23. PublicKey pub = pair.getPublic();  
  24. dsa.initVerify(pub);  
  25.     
  26. /* 데이터를 넣고, 서명검증 */  
  27. dsa.update(data);  
  28. boolean verifies = dsa.verify(sig);  
  29. System.out.println("signature verifies: " + verifies);  

[소스코드1] 전자서명/검증 예제 소스코드

[그림1]과 [소스코드1]은 간단한 전자서명과 검증 예를 설명하고 있습니다. 위와 같이 JCA에서는 키생성, 전자서명/검증을 위한 API를 제공하고 그 외에 다양한 확장 기능을 제공합니다.

 

  • 암호화


[그림2] 암복호화 설명도

 

  1. // 대칭키와 IV 설정
  2. SecretKey myKey = ...  
  3. byte[] myAAD = ...  // 'Additional Associated Data' 로 무결성 확인 용도
  4. byte[] plainText = ...  
  5. int myTLen = ...   
  6. byte[] myIv = ...  
  7.     
  8. // AES GCM모드 암호화를 위한 파라미터 설정
  9. GCMParameterSpec myParams = new GCMParameterSpec(myTLen, myIv);  
  10. Cipher c = Cipher.getInstance("AES/GCM/NoPadding");  
  11. c.init(Cipher.ENCRYPT_MODE, myKey, myParams);  
  12.     
  13. // 암호화  
  14. c.updateAAD(myAAD);  // if AAD is non-null  
  15. byte[] cipherText = new byte[c.getOutputSize(plainText.length)];  
  16. c.doFinal(plainText, 0, plainText.length, cipherText
  17.     
  18. // 복호화를 위한 Cipher 클래스 설정 및 복호화
  19. c.init(Cipher.DECRYPT_MODE, myKey, myParams);  
  20. c.updateAAD(myAAD);  
  21.  
  22. byte[] recoveredText = c.doFinal(cipherText);  
  23.     
  24. // GCM모드에서 동일키 사용을 위한 IV 재생성  
  25. byte[] newIv = ...;  
  26. myParams = new GCMParameterSpec(myTLen, newIv);  

[소스코드2] 암복호화 예제 소스코드


[그림2]와 [소스코드2]는 간단한 대칭키 암호화 예(AES GCM모드)를 설명하고 있습니다. 평문, 대칭키, IV(Initial Vector), ParameterSpec을 설정하고 Cipher.doFinal 메소드를 통해서 암복호화를 할 수 있습니다.

 

  • MAC(Message Authentication Code)

[그림 3] MAC 설명도

  1. import java.security.*;  
  2. import javax.crypto.*;  
  3.     
  4. public class initMac {  
  5.     
  6.     public static void main(String[] args) throws Exception {  
  7.     
  8.         // Generate secret key for HMAC-MD5  
  9.         KeyGenerator kg = KeyGenerator.getInstance("HmacMD5");  
  10.         SecretKey sk = kg.generateKey();  
  11.     
  12.         // Get instance of Mac object implementing HMAC-MD5, and  
  13.         // initialize it with the above secret key  
  14.         Mac mac = Mac.getInstance("HmacMD5");  
  15.         mac.init(sk);  
  16.         byte[] result = mac.doFinal("Hi There".getBytes());  
  17.     }  
  18. }  

[소스코드3] MAC 설명도


[그림3]와 [소스코드3]은 MAC(Message Authentication Code)을 설명하고 있습니다. 메시지("Hi There")의 MAC값을 생성하고, 이후 'Secret Key'를 공유하여 MAC값이 동일한지를 비교합니다.

 

  • Generators 와 Factories

[그림4] Generators와 Factories 설명도


[그림4]에서 보시는 바와 같이 Generator 클래스는 새로운 오브젝트(대칭키 등) 생성을 위한 파라미터를 설정하고, Factory 클래스는 이전에 정의된 오브젝트를 변환할 때 사용됩니다.

 

  • KeyFactory 클래스

[그림5] KeyFactory 클래스 설명도


[그림5]에서 보시는 바와 같이 KeyFactory 클래스는 'Key Spec'으로부터 'Key'를 생성하기도 하고, 반대로 'Key'로부터 'Key Spec'을 추출할 수 있습니다. 'Key Spec'에는 'Key'에 대한 정보가 포함되어 있습니다.

 

  • SecretKeyFactory 클래스

[그림6] SecretKeyFactory 클래스 설명도


[그림6]에서 보시는 바와 같이 'SecretKeyFactory' 클래스는 'Key Spec'에서 대칭키('Secret Key')를 생성할 수 있고, 대칭키로부터 'Key Spec'을 가져올 수 있습니다.

 

  • KeyPairGenerator 클래스

[그림7] KeyPairGenerator 클래스 설명도


[그림7]은 KeyPairGenerator가 두가지 방법으로 공개키/개인키를 생성하는 것을 보여줍니다. 하나는 알고리즘 독립적으로 키를 생성하는 방법이고, 다른 하나는 알고리즘을 정해서 키를 생성하는 방법입니다.

 

  • KeyGenerator 클래스

[그림8] KeyGenerator 클래스 설명도


[그림8]은 KeyGenerator 클래스가 대칭키를 생성하는 방법을 보여줍니다. 마찬가지로 알고리즘을 정해서 생성하는 방법과 그렇지 않은 방법이 있습니다.

 

  • KeyAgreement 클래스

[그림9] KeyAgreement 클래스 설명도


[그림9]은 Alice와 Bob이 DH 'Key Agreement'를 하는 과정을 보여줍니다. 공개키를 서로 교환하고 'Secret Key'를 생성하여 동일한지를 비교합니다.

 

  • KeyStore 클래스

[그림10] KeyStore 클래스


[그림10]는 KeyStore 클래스를 보여줍니다. 신뢰된 인증기관 인증서(Trusted Certificate), 공개키/개인키, 대칭키를 저장/추출할 수 있고, 파일 형태로 저장되는 것을 알 수 있습니다.

 



2. JCE(Java Cryptography Extension)

JCE는 JCA보다 더 강력한 확장된 보안 기능을 제공합니다. 미국에서 보안상 이유로 2000년 이후에나 해외로 보급되었습니다.[5]


[그림11] JCA와 JCE 구조 설명도

[그림11]에서 보시는 것처럼 JCA(java.security 패키지)와 JCE(javax.crypto 패키지)가 분리되어 있는 것을 알 수 있습니다. JDK1.4 이상부터는 모두 기본으로 포함되어 있습니다.

JCE에 포함되는 클래스는 Cipher, KeyGenerator, SecretKeyFactor, KeyAgreement, MAC 등입니다.


여기서 SUN JCE와 BouncyCastle 을 비교하겠습니다. [3][4]

  

장점

단점

SUN JCA/JCE 

- JDK에 포함되어 있음
- 'provider'를 선택해서 사용할 수 있음

- JDK 별로 provider가 일치하지 않아서 동작하지 않을 수 있음 (Java mobile 등)
- 알고리즘을 많이 제공하지 않음

Bouncy

Castle 

- JCA보다 많은 알고리즘을 지원

* SEED128 알고리즘 지원
- 사용에 아무런 제한이 없음(128비트 암호키 제한 등[5])

- 라이브러리 파일을 프로젝트에 추가시켜야함

[표2] JCA/JCE 와 BouncyCastle 비교


[표2]에서 보시는 것처럼 BouncyCastle이 더 많은 알고리즘 지원 및 호환성이 좋은 것을 알 수 있습니다. 특히, 국산암호알고리즘 SEED를 지원하므로 더 많은 곳에 사용할 수 있습니다.[4]

 

 '암호알고리즘사용제한' 제거 설정

- [참고8]에서 정책 파일을 다운로드하고, zip 압축을 푼 후에, local_policy.jar, US_export_policy.jar 파일을 $JAVA_HOME/jre/lib/security 에 복사하면 됩니다. [6][7][8]

※ 자바암호패키지(JCA/JCE)는 JDK1.4이상에서 기본으로 포함되어 있기 때문에 별도의 설치 방법이나 활용 방법을 설명하지 않습니다.


 

 

이번 글에서는 JAVA에서 기본으로 지원하는 암호 패키지인 JCA와 JCE에 대해서 알아보았습니다. 기본적인 키생성, 암호화, 전자서명 등은 JCA/JCE로 가능합니다. 하지만 JDK별로 호환이 안 되는 경우가 있고, 많은 알고리즘을 지원하지 않기 때문에 BouncyCastle 등의 암호 패키지를 사용하는 것이 좋겠습니다.


 

 

참고 목록

[1] https://en.wikipedia.org/wiki/Java_Cryptography_Architecture

[2] http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html

[3] https://blog.idrsolutions.com/2016/08/which-security-implementation-should-i-use-bouncy-castle-or-jca/

[4] http://bouncycastle.org/specifications.html

[5] https://en.wikipedia.org/wiki/Export_of_cryptography_from_the_United_States

[6] http://opensourceforgeeks.blogspot.kr/2014/09/how-to-install-java-cryptography.html

[7] http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#importlimits

[8] http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

 

 

문서 이력

- v1.00(2016.09.01) : 최초 등록

반응형
Posted by IT반장