everydayminder

learn something everyday

Archive for the ‘Hibernate’ Category

jasypt 사용중 org.jasypt.exceptions.EncryptionOperationNotPossibleException가 발생한다면?

leave a comment »

먼저, encrypt에 사용한 설정이 decrypt에 사용한 설정과 동일한지 확인하자.
그리고, DB의 필드가 충분히 긴지 확인하자.

나의 경우는, 위의 두 경우와 다른 경우였다.
output type을 default인 Base64에서 Hexadecimal로 변경하니, 위의 문제가 해결되었다.

이에 대한, jasypt의 공식 FAQ는 다음과 같다.

I keep on receiving EncryptionOperationNotPossibleException exceptions when trying to decrypt my data.
EncryptionOperationNotPossibleException is a very general exception which jasypt raises whenever there is a problem with encryption or decryption operations. It does not provide any further information to prevent the encryption infrastructure from showing too much information about what is going on (we wouldn’t want an attacker to get any algorithm-specific errors…)

When you get that error while decrypting, most of the times it will simply mean that the encrypted string you input was not adequate for the algorithm/password/keyObtentionIterations configuration you provided. Check that your encryptor is configured in exactly the same way as the one with which you originally encrypted the data.

Also, if you are storing your encrypted data into a database, check that the table columns that you use to store it are big enough to host the encrypted data (which is always bigger than the original data). If you are transmitting your encrypted data via HTTP, check that you are not having problems with the transmission of BASE64-encoded data as URL parameters (BASE64 uses characters which are forbidden in URL parameters, like “=”). For these uses, try using hexadecimal output.

Written by everydayminder

July 24, 2013 at 08:55

Posted in Hibernate, java

jasypt의 type 선언 : annotation에서 xml로 변경해보기

leave a comment »

annotation 방식의 특성상, 정밀한 설정에는 용이하나 jasypt를 적용하면서 사용할 model 클래스에 매번 적어줘야 한다면,

역시 “불편”할 것이다.

그럴 때는, 역시 xml의 선언이 훨씬 편리할 것이다.

1. annotation 방식


@TypeDef (name="encryptedString", typeClass=EncryptedStringType.class,
 parameters={@Parameter(name="encryptorRegisteredName", value="strongHibernateStringEncryptor")})

2. XML 방식

XML로 객체를 만들지 않고, annotation을 사용하여 만든 상황에서 hbm.xml을 만들어 사용하는 식으로 연결을 해보았다.

hibernate-configuration과 hibernate-mapping은 다른 dtd를 사용하기에 별도의 파일로 만들었다.

 <?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.luran.jasypt_test">
 <typedef name="encryptedString" class="org.jasypt.hibernate.type.EncryptedStringType">
 <param name="algorithm">PBEWithMD5AndTripleDES</param>
 <param name="password">jasypt</param>
 <param name="keyObtentionIterations">1000</param>
 </typedef>
 </hibernate-mapping>
 

현재 jasypt.org에 안내된 가이드는 1.9 기준이기 때문에, 해당 클래스가

org.jasypt.hibernate4.type.EncryptedStringType

로 되어있다.  본 테스트에서 사용한 버전은 1.8이기에 위와 같이 변경해줘야 제대로 인식이 된다. (namespace가 변경된 것 같음)

이제 기존에 작성한 hibernate.cfg.xml에서 이 mapping.hbm.xml을 읽어들이도록 변경해주자.

hibernate-configuration.dtd에 보면, mapping attribute가 있다. 이 attribute에 방금 작성한 파일을 지정한다.

 <hibernate-configuration>
 <session-factory>
 ...
 <mapping resource="META-INF/mapping.hbm.xml"/>
 ...
 </session-factory>
 </hibernate-configuration>
 

앞서 작성한 annotation 방식 typedef를 주석처리하고, 이제 다시 실행시켜 보자.
동일하게 동작하는 것을 확인할 수 있다.

Written by everydayminder

July 11, 2013 at 08:30

Posted in Hibernate, java

Spring3.1 + Hibernate3 + jasypt1.8 연동테스트

leave a comment »

기존에 Spring 3.1과 Hibernate 3을 사용중이었는데,
DB에 저장된 데이터를 암호화해야 할 일이 생겼다.

Hibernate를 사용한 목적에 맞도록, 암호화도 DBMS에 transparent한 솔루션으로 적용하고 싶다.
조사해보니, jasypt라는 라이브러리를 사용하면 이를 비교적 적은 비용으로 구현이 가능한 것 같아 설치 테스트해 보았다.

jasypt.는 (Java Simplified Encryption)이라는 뜻이며, 공식 사이트는 http://www.jasypt.org 이다.
2013/7/11 현재 최신 버전은 1.9.0이지만, 중앙 maven repository에 올라와 있는 버전으로는 1.8이고,
Hibernate 관련 라이브러리가 1.8에는 동봉되어 있으나, 1.9.0에는 별도 관리되고 있는 것 같다.
(결국, maven 테스트의 편리성 때문에 그냥 1.8로 테스트를 진행했다.)

1. Maven Dependency 추가
pom.xml에 다음의 내용을 추가하였다.

<!-- Jasypt -->
<dependency>
    <groupId>org.jasypt</groupId>
    <artifactId>jasypt</artifactId>
    <version>1.8</version>
</dependency>

2. Spring bean 등록 (application-context.xml에 등록)

<bean id="strongEncryptor" class="org.jasypt.encryption.pbe.PooledPBEStringEncryptor">
    <property name="algorithm">
        <value>PBEWithMD5AndTripleDES</value>
    </property>
    <property name="password">
        <value>cUst0mP@sswOrd</value>
	<!-- Put whatever you want, it must be unique and strong -->
    </property>
    <property name="poolSize">
<value>4</value>
	<!-- to be optimal, put the number of cores of your processor-->
    </property>
</bean>

<bean id="hibernateStringEncryptor" class="org.jasypt.hibernate.encryptor.HibernatePBEStringEncryptor">
    <property name="registeredName">
        <value>strongHibernateStringEncryptor</value>
    </property>
    <property name="encryptor">
        <ref bean="strongEncryptor"/>
    </property>
</bean>

3. Type 정의

http://www.jasypt.org에는 hibernate.cfg.xml에 환경 설정을 등록하는 방법과, Spring내에서 annotation으로 등록하는 방법을 가이드하고 있는데,

어차피 Spring에서 annotation을 사용하고 있으므로, 그냥 model 클래스에 선언하여 사용해 보았다.

해당 model(entity) 클래스에 다음과 같이 적어준다.


@TypeDef (name="encryptedString", typeClass=EncryptedStringType.class,
 parameters={@Parameter(name="encryptorRegisteredName", value="strongHibernateStringEncryptor")})

4. 코드내 적용

이제 암호화를 원하는 필드에 위의 타입을 annotation으로 적용하자.

@Type(type="encryptedString")
public String getName() {
    return name;
}

별도의 decryption 옵션을 지정하지 않아도, 이제 model 객체는 자동으로 encrypt/decrypt를 수행하며,

해당 model을 사용하는 DAO들은 별도의 수정작업이 없이도 해당 model의 일부 필드를 암호화할 수 있게 되었다.

5.  기타 : JCE 설정

jasypt를 설치/테스트하는 도중, JVM내 JCE가 설치되어 있지 않은 것 같다는 에러 메시지가 떴었다.

오라클 공식 홈페이지에서 JCE 관련 파일을 받아서 설치하자.

Java SE Downloads 메뉴로부터 스크롤하여, Additional Resources부분을 살펴보면,

Java Cryptography Extension(JCE) Unlimited Strength jurisdiction Policy Files를 발견할 수 있을 것이다.

이 파일을 다운로드하여, 파일내 들어있는 jar파일들을 $JAVA_HOME/jre/lib/security에 풀어넣자. (기존에 있던 동일 이름의 파일들은

다른 곳에 복사해두자.)

이제 다시 실행시켜보면, 기존에 발생하던 JCE 라이브러리가 없다는 에러가 발생하지 않을 것이다.

6. 기타 : Hibernate 검색 관련

잠시만 생각해보면 당연하겠지만, 기존에 Hibernate의 criteria등을 써서 검색에 사용하던 필드가 암호화 대상 필드가 되었다면?

검색이 되지 않는다. 기본적으로 random salt를 사용하기 때문에 같은 값이라 하더라도, 다른 암호화 값으로 변화할 것이다.

동일한 ‘test’라는 문자열을 암호화했으나, salt가 달라서  다음과 같이 다르게 암호화 문자열이 생성된다.


Jq4AjAaYAjgM7oTJHySLZw==
bjMPhCbaL3fxgg+3KquOoA==

Random이 아닌 Fixed Salt Generator를 사용한다면? 같은 암호 문자열은 얻을 수 있을지 모르지만, 덜 안전한 데이터 관리방안이 될 것이다.

게다가, == 연산 이외의 >,< 등의 연산이나 like 와 같은 연산은 사용할 수 없게 될테니 주의하자. (= 설계부터 잘 하자.)

Written by everydayminder

July 11, 2013 at 07:06

Posted in Hibernate, java

@Entity 모델 객체는 Serializable을 꼭 구현해야 하나?

leave a comment »

“JSR 220: Enterprise JavaBeansTM,Version 3.0 Java Persistence API Version 3.0, Final Release May 2, 2006″에 따르면,

다음과 같이 기술하고 있다.

“If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface.”

따라서, 이 객체를 어딘가로 전송하거나 세션에 기록하거나 등등 정말 serialization을 위한 용도가 아니라면,

Hibernate상에서는 굳이 Serailizable을 구현하지 않아도 된다는 뜻이지만,

사람들은 흔히 권하기를 그래도 웬만하면 Serializable을 구현하는 것이 좋은 습관일 것이라고 권한다.

 

실제 임의의 클래스를 작성하여, implements Serializable을 하거나, 하지 않더라도 정상적으로 DB에 persist되는 것을 확인할 수 있다.

 

Written by everydayminder

July 10, 2013 at 10:25

Posted in Hibernate

Unknown Entity Exception : @Entity 사용시

leave a comment »

Hibernate를 사용하여, @Entity annotation을 사용하여 객체를 만들어 사용할 경우,

유의할 점이 있다.

@Entity를 import할 때,


org.hibernate.annotations.Entity
javax.persistence.Entity

의 두 가지 중에, 선택해야할 것은 javax.persistence.Entity이다.

위의 옵션을 선택한 경우, Unknown Entity Exception이 발생한다. Hibernate 4.1 이후 org.hibernate.annotations.Entity 는 deprecated 된다고 한다.

결론) javax.persistence.Entity를 import 하자.

Written by everydayminder

July 10, 2013 at 04:20

Posted in Hibernate