자바암호패키지 (JCA, JCE) 및실무활용방법 20soft 박대표 이글에서는자바암호패키지인 JCA(Java Cryptography Architecture) 와 JCE(Java Cryptography Extension) 에대해서알아보고, 실무활용방법에대해서알아보겠습니다. 안녕하세요. 박대표 (^O^) 입니다. 최근에많은프로그램들이자바언어로만들어지고있습니다. 서버프로그램뿐만아니라클라이언트프로그램도자바언어로프로그래밍되는경우가많습니다. ( 예, 스프링프레임워크, 안드로이드등 ) 그리고자바언어에서는암호화를위해 JCA(Java Cryptography Architecture) 와 JCE(Java Cryptography Extension) 패키지를제공하고있습니다. 이글에서는암호프로그래밍에서쉽게자주접하게되는 JCA 와 JCE 에대해서알아보고실무활용방법을설명하겠습니다. 1
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): 네트워크보안기능제공 2
구조 [ 그림 0] MD5 메시지다이제스트구현설명도 [ 그림 0] 에서보듯이각각의어플리케이션은 Provider Framework 를통해서각각의독립적인 Provider 에 접근해서암호기능을구현할수있습니다. 키관리 - 키와인증서들의저장소를관리하는 keystore 가있습니다. - java.security.keystore 클래스 -.jks 파일형태로구현됨 ( 또는 3DES 로암호화된.jceks) - 어플리케이션은각각의 Provider 로부터개별적인 keystore 구현가능 주요클래스 클래스명 ( 인터페이스명 ) 내용 Provider Security SecureRandom MessageDigest Signature 기본 Provider 클래스 Provider' 및 'security property' 관리난수 (random number) 생성해시값생성전자서명 & 검증 3
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 CertPathBuilder CertPathValidator CertStore 키타입변환대칭키타입변환공개키 / 개인키생성대칭키생성키교환정보키관리알고리즘파라미터알고리즘파라미터생성인증서, 인증서폐기목록 (CRL) 생성인증서체인생성인증서체인검증인증서, 인증서폐기목록 (CRL) 관리 [ 표 1] JCA 주요클래스 4
전자서명 [ 그림 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 를제공하고그외에다양한확장기능을제공합니다. 5
암호화 [ 그림 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 메소드를통해서암복호화를할수있습니다. 6
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 값이동일한지를비교합니다. 7
Generators 와 Factories [ 그림 4] Generators 와 Factories 설명도 [ 그림 4] 에서보시는바와같이 Generator 클래스는새로운오브젝트 ( 대칭키등 ) 생성을위한파라미터를 설정하고, Factory 클래스는이전에정의된오브젝트를변환할때사용됩니다. KeyFactory 클래스 [ 그림 5] KeyFactory 클래스설명도 [ 그림 5] 에서보시는바와같이 KeyFactory 클래스는 Key Spec 으로부터 Key 를생성하기도하고, 반대로 Key 로부터 Key Spec 을추출할수있습니다. Key Spec 에는 Key 에대한정보가포함되어있습니다. 8
SecretKeyFactory 클래스 [ 그림 6] SecretKeyFactory 클래스설명도 [ 그림 6] 에서보시는바와같이 SecretKeyFactory 클래스는 Key Spec 에서대칭키 ( Secret Key ) 를생성할수 있고, 대칭키로부터 Key Spec 을가져올수있습니다. KeyPairGenerator 클래스 [ 그림 7] KeyPairGenerator 클래스설명도 [ 그림 7] 은 KeyPairGenerator 가두가지방법으로공개키 / 개인키를생성하는것을보여줍니다. 하나는알고리즘 독립적으로키를생성하는방법이고, 다른하나는알고리즘을정해서키를생성하는방법입니다. 9
KeyGenerator 클래스 [ 그림 8] KeyGenerator 클래스설명도 [ 그림 8] 은 KeyGenerator 클래스가대칭키를생성하는방법을보여줍니다. 마찬가지로알고리즘을정해서 생성하는방법과그렇지않은방법이있습니다. KeyAgreement 클래스 [ 그림 8] KeyAgreement 클래스설명도 [ 그림 8] 은 Alice 와 Bob 이 DH Key Agreement 를하는과정을보여줍니다. 공개키를서로교환하고 Secret Key 를생성하여동일한지를비교합니다. 10
KeyStore 클래스 [ 그림 9] KeyStore 클래스 [ 그림 9] 는 KeyStore 클래스를보여줍니다. 신뢰된인증기관인증서 (Trusted Certificate), 공개키 / 개인키, 대칭키를저장 / 추출할수있고, 파일형태로저장되는것을알수있습니다. 2. JCE(Java Cryptography Extension) JCE 는 JCA 보다더강력한확장된보안기능을제공합니다. 미국에서보안상이유로 2000 년이후에나해외로 보급되었습니다.[5] [ 그림 10] JCA 와 JCE 구조설명도 [ 그림 10] 에서보시는것처럼 JCA(java.security 패키지 ) 와 JCE(javax.crypto 패키지 ) 가분리되어있는것을알수있습니다. JDK1.4 이상부터는모두기본으로포함되어있습니다. JCE 에포함되는클래스는 Cipher, KeyGenerator, SecretKeyFactor, KeyAgreement, MAC 등입니다. 여기서 SUN JCE 와 BouncyCastle 을비교하겠습니다. [3][4] 11
SUN JCA/JCE Bouncy Castle 장점단점 - JDK 별로 provider 가일치하지않아서 - JDK 에포함되어있음동작하지않을수있음 (Java mobile 등 ) - 'provider' 를선택해서사용할수있음 - 알고리즘을많이제공하지않음 - JCA 보다많은알고리즘을지원 * SEED128 알고리즘지원 - 라이브러리파일을프로젝트에추가시켜야함 - 사용에아무런제한이없음 (128 비트암호키제한등 [5]) [ 표 2] JCA/JCE 와 BouncyCastel 비교 [ 표 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 등의암호패키지를사용하는것이좋겠습니다. 회사의보안비용을절감하고보안성을높이는첫번째시작은 오픈소스암호라이브러리 의활용입니다. 이문서는 http://securitypark.tistory.com 이외에는재배포를허용하지않습니다. 12
참고목록 [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-usebouncy-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-javacryptography.html [7] http://docs.oracle.com/javase/8/docs/technotes/guides/security/sunproviders.html#impor tlimits [8] http://www.oracle.com/technetwork/java/javase/downloads/jce8-download- 2133166.html 문서이력 - v1.00(2016.09.01) : 최초등록 13