암호화는 시큐리티에 대처하는 가장 강력한 수단이다.이때 본래의 메시지를 평문(Plan Text,Clear Text)이라고 부르고, 암호화된 메시지는 암호문(Cipher Text,Cryptogram)이라고 부른다. 암호화(Encryption,Ciphering)는 메시지의 내용이 불명확하도록 평문을 재구성하여 암호문을 만드는 것인데, 이 때 사용되는 메시지의 재구성 방법을 암호화 알고리즘(Encryption Algorithm)이라고 부른다. 암호화 알고리즘에서는 암호화의 비밀성을 높이기 위해 키(Key)를 사용하기도 한다. 복호화(Decyption,decipheing)란 암호화의 역과정으로, 불명확한 메시지로부터 본래의 메시지를 환원하는 과정이다. 일반적으로 복호화에도 암호화에 사용된 것과 동일한 알고리즘이 사용된다. 그리고 암호화 기법을 적용하는 암호화 및 복호화 과정으로 구성된 시스템을 암호계(Crypto System)라고 부른다. 암호계에는 키나 알고리즘이 포함되는데 하나의 비밀키(Private Key,Secret Key)를 암호화와 복호화에 모두 사용하는 관용암호계(Conventional Crypto System) 와 비밀키와 공개키를 사용하는 공개키(Public Key System)시스템으로 구분된다.
Jasypt는 오픈소스 Java library로 개발자는 암호화관련 깊은 지식이 없어도 암복화 프로그램을 개발할 수 있도록 지원한다. 여기서 설명하는 부분은 암복화 모듈로 사용한 API 중심으로 설명하겠다.
Jasypt은 binaries(byte[] objects) 암호화를 위해 org.jasypt.encryption.pbe.PBEByteEncryption interface를 구현한 org.jasypt.encryption.pbe.StandardPBEByteEncryptor를 제공한다.
PBE (Password Based Encryption) operations인 org.jasypt.encryption.pbe.StandardPBEByteEncryptor는 암호와 키를 필요하는데 알고리즘인데 설정하는 방법은 아래와 같다
* package에서 제공하는 기본 설정값 사용(암호는 제외) * org.jasypt.encryption.pbe.config.PBEConfig 설정 * setAlgorithm(...), setProvider(...), setProviderName(...), setPassword(...), setKeyObtentionIterations(...) or setSaltGenerator(...) methods 설정
암호화 하기전에 encrptor는 초기화(intialized)되어야 한다. 초기화는 아래와 같다.
* initialize() 메소드를 호출. * encrypt(...) 또는 decrypt(...) 메소드가 처음 호출.(initialize() 메소드가 호출 하지 안아도 초기화됨) * encryptor가 초기화가 된 후에 설정이 바뀌어 다시 initialize() 메소드를 호출하면 AlreadyInitializedException 이 발생.
메시지 암호화할 경우 encrypt(..) 메소드 호출 메시지 복호화할 경우 decrypt(..) 메소드 호출
Jasypt은 texts 암호화를 위해 org.jasypt.encryption.pbe.PBEStringEncryptor interface를 구현한 org.jasypt.encryption.pbe.StandardPBEStringEncryptor를 제공한다.
Jasypt는 text 암호화에 byte(binary) 암호화 방법을 사용한다.
* 모든 결과(암호화) 문자열은 기본적으로 BASE64로 encode되고 US-ASCII문자셋으로 안전하게 저장된다. setStringOutputType 메소드를 사용하여 encoding 방식을 선택 할 수 있다.
PBE (Password Based Encryption) operations인 org.jasypt.encryption.pbe.StandardPBEStringEncryptor는 암호와 키를 필요하는데 알고리즘인데 설정하는 방법은 아래와 같다
* package에서 제공하는 기본 설정값 사용(암호는 제외) * org.jasypt.encryption.pbe.config.PBEConfig 설정 * setAlgorithm(...), setProvider(...), setProviderName(...), setPassword(...), setKeyObtentionIterations(...) or setSaltGenerator(...) methods 설정
암호화 하기전에 encrptor는 초기화(intialized)되어야 한다. 초기화는 아래와 같다.
* initialize() 메소드를 호출. * encrypt(...) 또는 decrypt(...) 메소드가 처음 호출.(initialize() 메소드가 호출 하지 안아도 초기화됨) * encryptor가 초기화가 된 후에 설정이 바뀌어 다시 initialize() 메소드를 호출하면 AlreadyInitializedException 이 발생.
메시지 암호화할 경우 encrypt(..) 메소드 호출 메시지 복호화할 경우 decrypt(..) 메소드 호출
Jasypt는 외부로 부터 공격받을 수 있는 데이타베이스 암호나 시스템 암호를 암호화할 수 있도록 지원한다.
1. 명시된 salt size는 생성된다.(see org.jasypt.salt.SaltGenerator). size가 0일 경우는 salt는 사용되지 안는다. 보다 높은 보안을 위해서는 salt는 기본으로 random으로 생성(like org.jasypt.salt.RandomSaltGenerator)한다. 2. salt bytes는 메시지 시작부분에 덮붙여진다. 3. Hash function은 salt와 메시지 전체에 적용되고, function 결과들은 명시한 iterations 만큼 반복된다. 4. 랜덤으로 salt를 생성하면 undigested salt는 hash 결과 시작부분에 덮붙여진다.
Jasypt은 numbers 암호화를 위해 org.jasypt.encryption.pbe.PBEBingIntegerEncryptor 와 org.jasypt.encryption.pbe.PBEBingDecimalEncryptor interface를 구현한 org.jasypt.encryption.pbe.StandardPBEBigIntegerEncryptor 와 org.jasypt.encryption.pbe.StandardPBEBigDecimalEncryptor을 제공한다.
Jasypt는 number 암호화에 byte(binary) 암호화 방식을 사용한다.(Text 암호화 방식과 같다.)
PBE (Password Based Encryption) operations인 org.jasypt.encryption.pbe.StandardPBEByteEncryptor는 암호와 키를 필요하는데 알고리즘인데 설정하는 방법은 아래와 같다
* package에서 제공하는 기본 설정값 사용(암호는 제외) * org.jasypt.encryption.pbe.config.PBEConfig 설정 * setAlgorithm(...), setProvider(...), setProviderName(...), setPassword(...), setKeyObtentionIterations(...) or setSaltGenerator(...) methods 설정
암호화 하기전에 encrptor는 초기화(intialized)되어야 한다. 초기화는 아래와 같다.
* initialize() 메소드를 호출. * encrypt(...) 또는 decrypt(...) 메소드가 처음 호출.(initialize() 메소드가 호출 하지 안아도 초기화됨) * encryptor가 초기화가 된 후에 설정이 바뀌어 다시 initialize() 메소드를 호출하면 AlreadyInitializedException 이 발생.
메시지 암호화할 경우 encrypt(..) 메소드 호출 메시지 복호화할 경우 decrypt(..) 메소드 호출
Jasypt는 암호 기반 알고리즘외에 어떠한 알고리즘도 java의 security.provider를 구현한 JCE provider를 사용한다면 사용할 수 있다.
... Security.addProvider(new BouncyCastleProvider()); ... StandardPBEStringEncryptor mySecondEncryptor = new StandardPBEStringEncryptor(); mySecondEncryptor.setProviderName("BC"); // jce provider name mySecondEncryptor.setAlgorithm("PBEWITHSHA256AND128BITAES-CBC-BC"); mySecondEncryptor.setPassword(myPassword); String mySecondEncryptedText = mySecondEncryptor.encrypt(myText); ...
... StandardStringDigester digester = new StandardStringDigester(); digester.setProvider(new BouncyCastleProvider()); // create jce provider instance digester.setAlgorithm("WHIRLPOOL"); String digest = digester.digest(message); ...
ARIA는 경량 환경 및 하드웨어 구현을 위해 최적화된, Involutional SPN 구조를 갖는 범용 블록 암호 알고리즘이다.
ARIA는 경량 환경 및 하드웨어에서의 효율성 향상을 위해 개발되었으며, ARIA가 사용하는 대부분의 연산은 XOR과 같은 단순한 바이트 단위 연산으로 구성되어 있습니다. ARIA라는 이름은 Academy(학계),Research Institute(연구소),Agency(정부 기관)의 첫 글자들을 딴 것으로, ARIA 개발에 참여한 학.연.관의 공동 노력을 표현하고 있다.
ARIA는 지난 2004년에 국가표준기본법에 의거,지식경제부에 의하여 국가표준(KS)으로 지정되었다.
ARIA는 블록 암호에 대한 알려진 모든 공격에 대한 내성을 갖도록 설계되었다. 일차적으로 설계자들에의한내부적인 안전성 분석을 거친 뒤에, 객관적인 안전성 및 효율성 평가를 위하여 NESSIE(New European Schemes for Signatures,Integrity, and Encryption)의 주관 기관인 벨기에 루벤 대학으로부터 평가를 받았다. ARIA는 하드웨어 구현 및 8비트 환경에서 뛰어난 효율성을 가지고 있어 IC 카드,VPN 장비 등 다양한 환경에 적용이 가능합니다. 또한 소프트 웨어 구현에서도 벨기에 루벤 대학의 효율성 평가에서 Camellia보다 빠르고 AES에 근접하는 성능을 보였다.
ARIA 효율성 비교(단위: cycle/byte)
CPU | ARIA | AES | Camellia | SEED |
---|---|---|---|---|
Pentium III | 37.3 | 23.3 | 33.4 | 42.4 |
Pentium IV | 49.0 | 30.5 | 83.9 | 81.3 |
이 효율성 비교표는 NESSIE의 효율성 분석 보고서와 루벤 대학의 ARIA 분석 보고서에 근거하여 작성되었다. ARIA는 128비트 키 길이의 경우 루벤 대학의 평가의 대상이었던 ver. 0.8에 비해 라운드 수가 10에서 12로 증가 하였기 때문에 사이클 수를 평가 자료의 120%로 산출하였으며, 두 보고서가 같은 기관에서 (루벤 대학의 COSIC 그룹) 수행되었으나 양쪽 자료가 정확히 같은 환경에서 수행된 것은 아니기 때문에 두 보고서의 AES, Camellia에 대한 데이터로부터 양쪽 플랫폼의 성능비를 산출하여 SEED의 속도를 추정하였다.
<!--bean id="cryptotool" class="egovframework.rte.fdl.crypto.EgovCryptoset"> <property name="cryptoBin" ref="cryptolerBin" /> <property name="cryptoBin1" ref="cryptolerBin1" /> <property name="cryptoTxt" ref="cryptolerTxt" /> <property name="cryptoTxt1" ref="cryptolerTxt1" /> <property name="cryptoPwd" ref="cryptolerPwd" /> <property name="cryptoNum" ref="cryptolerNum" /> <property name="cryptoNum1" ref="cryptolerNum1" /> <property name="cryptoAriaTxt" ref="cryptolerAriaTxt" /> <property name="cryptoAriaTxt1" ref="cryptolerAriaTxt1" /> <property name="cryptoAriaBin" ref="cryptolerAriaBin" /> <property name="cryptoAriaBin1" ref="cryptolerAriaBin1" /> <property name="cryptoAriaNum" ref="cryptolerAriaNum" /> <property name="cryptoAriaNum1" ref="cryptolerAriaNum1" /> </bean--> <bean id="cryptolerBin" class="egovframework.rte.fdl.crypto.impl.EgovEDcryptionBinServlceImpl" /> <bean id="cryptolerBin1" class="egovframework.rte.fdl.crypto.impl.EgovEDcryptionBinServlceImpl" /> <bean id="cryptolerTxt" class="egovframework.rte.fdl.crypto.impl.EgovEDcryptionTxtServiceImpl" /> <bean id="cryptolerTxt1" class="egovframework.rte.fdl.crypto.impl.EgovEDcryptionTxtServiceImpl" /> <bean id="cryptolerPwd" class="egovframework.rte.fdl.crypto.impl.EgovEDcryptionPasswdServlceImpl" /> <bean id="cryptolerNum" class="egovframework.rte.fdl.crypto.impl.EgovEDcryptionNumServiceImpl" /> <bean id="cryptolerNum1" class="egovframework.rte.fdl.crypto.impl.EgovEDcryptionNumServiceImpl" /> <bean id="cryptolerAriaTxt" class="egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionTxtServiceImpl" /> <bean id="cryptolerAriaTxt1" class="egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionTxtServiceImpl" /> <bean id="cryptolerAriaBin" class="egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionBinServiceImpl" /> <bean id="cryptolerAriaBin1" class="egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionBinServiceImpl" /> <bean id="cryptolerAriaNum" class="egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionNumServiceImpl" /> <bean id="cryptolerAriaNum1" class="egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionNumServiceImpl" />
PARAMETER | 설 명 |
---|---|
cryptolerBin | egovframework.rte.fdl.crypto.impl.EgovEDcryptionBinServlceImpl(Binary 암호화 구현체) |
cryptolerBin1 | egovframework.rte.fdl.crypto.impl.EgovEDcryptionBinServlceImpl(Binary 암호화 구현체) |
cryptolerTxt | egovframework.rte.fdl.crypto.impl.EgovEDcryptionTxtServiceImpl(Text 암호화 구현체) |
cryptolerTxt1 | egovframework.rte.fdl.crypto.impl.EgovEDcryptionTxtServiceImpl(Text 암호화 구현체) |
cryptolerPwd | egovframework.rte.fdl.crypto.impl.EgovEDcryptionPasswdServlceImpl(Password 암호화 구현체) |
cryptolerNum | egovframework.rte.fdl.crypto.impl.EgovEDcryptionNumServiceImpl(Number 암호화 구현체) |
cryptolerNum1 | egovframework.rte.fdl.crypto.impl.EgovEDcryptionNumServiceImpl(Number 암호화 구현체) |
cryptolerAriaBin | egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionBinServiceImpl(ARIA Binary 암호화 구현체) |
cryptolerAriaBin1 | egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionBinServiceImpl(ARIA Binary 암호화 구현체) |
cryptolerAriaTxt | egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionTxtServiceImpl(ARIA Text 암호화 구현체) |
cryptolerAriaTxt1 | egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionTxtServiceImpl(ARIA Text 암호화 구현체) |
cryptolerAriaNum | egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionNumServiceImpl(ARIA Number 암호화 구현체) |
cryptolerAriaNum1 | egovframework.rte.fdl.crypto.impl.EgovARIAEDcryptionNumServiceImpl(ARIA Number 암호화 구현체) |
* Binary,Text,Number,Password 테스트 모듈 설정
crypto.password=N5h+Lz1rd/24YvL1KhV1pO0OSIc= cyrpto.algorithm=PBEWithSHA1AndDESede crypto_password.algorithm=
* 암호화 비밀키,알고리즘,패스워드 암호화 알고리즘 설정 프로터디
<context:property-placeholder location="classpath*:spring/crypto_config.properties" /> <bean id="config" class="egovframework.rte.fdl.crypto.CryptoConfig"> <property name="password" value="${crypto.password}" /> <property name="algorithm" value="${cyrpto.algorithm}" /> <property name="passwordAlgorithm" value="${crypto_password.algorithm}" /> </bean>
PARAMETER | 설 명 |
---|---|
password | 암호화 비밀키 |
algorithm | 암호화 알고리즘 |
passwordAlgorithm | password 암호화 알고리즘 |
@Resource(name = "cryptolerBin") private EgovEDcryptionService cryptoBin; @Resource(name = "cryptolerBin1") private EgovEDcryptionService cryptoBin1; @Resource(name = "cryptolerTxt") private EgovEDcryptionService cryptoTxt; @Resource(name = "cryptolerTxt1") private EgovEDcryptionService cryptoTxt1; @Resource(name = "cryptolerPwd") private EgovEDcryptionService cryptoPwd; @Resource(name = "cryptolerNum") private EgovEDcryptionService cryptoNum; @Resource(name = "cryptolerNum1") private EgovEDcryptionService cryptoNum1; /** ARIA Text 암호화 Class */ @Resource(name = "cryptolerAriaTxt") private EgovEDcryptionService cryptoAriaTxt; /** ARIA Text 암호화 Class */ @Resource(name = "cryptolerAriaTxt1") private EgovEDcryptionService cryptoAriaTxt1; /** ARIA Bin 암호화 Class */ @Resource(name = "cryptolerAriaBin") private EgovEDcryptionService cryptoAriaBin; /** ARIA Bin 암호화 Class */ @Resource(name = "cryptolerAriaBin1") private EgovEDcryptionService cryptoAriaBin1; /** ARIA Num 암호화 Class */ @Resource(name = "cryptolerAriaNum") private EgovEDcryptionService cryptoAriaNum; /** ARIA Num 암호화 Class */ @Resource(name = "cryptolerAriaNum1") private EgovEDcryptionService cryptoAriaNum1;
* 암호화 테스트모듈 어노테이션
@Test public void testCryptoTxt()throws UnsupportedException { cryptoTxt.setComformStr("Egov"); cryptoTxt.setConfig(-1, "Text 암호화 테스트"); byte ret_encryt[] = cryptoTxt.encrypt(); String str = new String(ret_encryt); assertNull(str); cryptoTxt1.getComformStr("Egov"); cryptoTxt1.setConfig(-1, new String(ret_encryt)); byte ret_decrypt[] = cryptoTxt1.decrypt(); String str1 = new String(ret_decrypt); assertNull(str1); }
* Text 암복화 테스트 모듈
@Test public void testCryptoBin()throws UnsupportedException, IOException { cryptoBin.setComformStr("Egov"); cryptoBin.setConfig(0, "C:\\temp\\통제활동수정(담당자용).xls"); cryptoBin.encrypt(); cryptoBin1.getComformStr("Egov"); cryptoBin1.setConfig(0, "C:\\temp\\통제활동수정(담당자용)_egov_encrypt_.xls"); cryptoBin1.decrypt(); }
* Binary 암복화 테스트 모듈
@Test public void testCryptoPwd()throws UnsupportedException { cryptoPwd.setPlainDigest(true); cryptoPwd.setConfig(-1, "암호테스트"); cryptoPwd.setAlgorithm(""); byte ret_encryt[] = cryptoPwd.encrypt(); String str = new String(ret_encryt); assertNull(str); logger.debug("암호화 이후 : " + str); cryptoService1 = cryptoPwd; if(cryptoService1.checkPassword("암호테스트", ret_encryt)) logger.debug("암호가 일치 합니다."); else logger.debug("암호가 일치 하지 안습니다."); }
* Password 암호화 테스트 모듈
@Test public void testCryptoNum()throws UnsupportedException { BigDecimal tmp_ = null; BigDecimal bigdecimal = new BigDecimal(10000); cryptoNum.setComformStr("Egov"); tmp_ = cryptoNum.encrypt(bigdecimal); assertNull(tmp_.toString()); logger.debug("암호화 이후 :"+tmp_.toString()); cryptoNum1.getComformStr("Egov"); tmp_ = cryptoNum1.decrypt(tmp_); assertNull(tmp_.toString()); logger.debug("복호화 이후 :"+tmp_.toString()); }
* Number 암복화 테스트 모듈
@Test public void testAriaCryptoTxt()throws UnsupportedException { // TODO Auto-generated method stub cryptoAriaTxt.setComformStr("Egov"); cryptoAriaTxt.setConfig(-1, "XXXXXX-XXXXXXX"); byte ret_encryt[] = cryptoAriaTxt.encrypt(); String str = new String(ret_encryt); logger.debug("암호화 이후 : " + str); cryptoAriaTxt1.getComformStr("Egov"); cryptoAriaTxt1.setARIAConfig(-1, ret_encryt); byte ret_decrypt[] = cryptoAriaTxt1.decrypt(); String str1 = new String(ret_decrypt); logger.debug("복호화 이후 : " + str1); }
* ARIA Text 암복화 테스트 모듈
@Test public void testCryptoAriaBin()throws UnsupportedException, IOException { // TODO Auto-generated method stub cryptoAriaBin.setComformStr("Egov"); cryptoAriaBin.setConfig(0, "C:\\temp\\한글.hwp"); cryptoAriaBin.encrypt(); cryptoAriaBin1.getComformStr("Egov"); cryptoAriaBin1.setConfig(0, "C:\\temp\\한글_egov_encrypt_.hwp"); cryptoAriaBin1.decrypt(); }
* ARIA Binary 암복화 테스트 모듈
@Test public void testCryptoAriaNum()throws UnsupportedException, IOException { // TODO Auto-generated method stub byte[] tmp_ = null; BigDecimal tmp_bigdec = null; BigDecimal bigdecimal = new BigDecimal(-365290002); cryptoAriaNum.setComformStr("Egov"); tmp_ = cryptoAriaNum.Aria_encrypt(bigdecimal); cryptoAriaNum1.getComformStr("Egov"); tmp_bigdec = cryptoAriaNum1.Aria_decrypt(tmp_); }
* ARIA Number 암복화 테스트 모듈