IT

패스워드 기반 암호화(PBE : Password-Based Encryption)

 

1  설명

   가) 패스워드를 키로 사용하는 방법

   나) 키 스페이스가 TripleDES나 Blowfish보다 훨씬 작아 안전하지 못함

   다) 사전공격에 취약함

   라) 해쉬와 일반적인 대칭 암호화를 사용함

   마) 미리 패스워드 해쉬 목록을 만들어 놓고 복호화 할 수 있음

   바) salting와 iteration counts를 도입하여 보안성 강화

 

2  방법

   가) 패스워를 MD5로 해쉬를 구한 다음 이 값을 암호화 키 값으로 사용한다. 

 

3  Salt

   가) 패스워드를 해쉬하기 전에 랜덤값을 추가하여 키 스페이스를 늘린다.

   나) salt는 암호문과 함께 저장된다.

   다) 복호화할 때는 암호화된 데이터로부터 salt를 분리해야 한다.

   라) salt는 매번 다르게 생성되며 동일한 문장에 대해서도 다른 값이 생성된다.

 

4  Iteration count

   가) 해쉬의 횟수를 의미함

   나) Iteration count가 1000이면 1000번을 해쉬한다는 의미

 

5  암호화/복호화 방법

   가) 패스워드와 salt를 생성하여 보통문서를 암호화하고 생성된salt를 암호문서 앞에 붙인다.

 

   나) 암호화된 데이타를 salt와 암호문서로 나누어 패스워드와 salt로 암호 문서를 복호화 한다.

 

 

6  주요 클래스 사용법

   가) PBEKeySpec : SecretKeyFactory의 인스턴스를 이용해서 패스워드기반 키를 생성한다.

 char[] password = “iloveyou”.toCharArry();

PBEKeySpec keySpec = new PBEKeySpec(password)

 

   나) SecretKeyFactory : PBEKeySpec을 실제 키로 사용하기 위해 generateSecret()를 실행시켜 줘야 한다.

 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(“PBEWithShAAndTwoFish-CBC”);

SecretKey theKey = keyFactory.generateSecret(keySpec);

 

   다) PBEParameterSpec : salt와 interation count를 위한 레퍼런스

 PBEParameterSpec paramSpec = new PBEParameterSpec(salt, iterations);

Cipher cipher = Cipher.getInstance(“PBEWithShAAndTwoFish-CBC”);

Cipher.init(Cipher.ENCRYPT_MODE, theKey, paramSpec);

 

7  PBE 알고리즘

   가) PBEWithMD5AndDES 

   나) PBEWithSHAAndBlowfish

   다) PBEWithSHAAnd128BitRC4

   라) PBEWithSHAAndDEA-CBC

   마) PBEWithSHAAnd3-KeyTripleDES-CBC

 

8  PBE 예제

 

 import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import com.Ostermiller.util.Base64;

public class PBE {

 private static int ITERATIONS = 1000;
 
 public static void main(String[] args) {
  char[] password = "iloveyou".toCharArray();
  String text = "i love you! but you don't. i sad b.b";
  String output = null;
  
  System.out.println("평문 : " + text);
  try {
   output = encrypt(password, text);
   System.out.println("암호문 : " + output);
   System.out.println("복호문 : " + decrypt(password, output));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 private static String encrypt(char[] password, String plaintext) throws Exception {
  // 1. salt를 8byte 랜덤 생성
  byte[] salt = new byte[8];
  Random random = new Random();
  random.nextBytes(salt);
  
  // 2. 패스워드를 이용하여 PBEKeySpec 생성
  PBEKeySpec keySpec = new PBEKeySpec(password);
  SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHAAndTwoFish-CBC");
  
  // 3. 비밀키 생성
  SecretKey key = keyFactory.generateSecret(keySpec);
  
  // 4. salt, iteration count를 위한 PBEParameterSpec 생성
  PBEParameterSpec paramSpec = new PBEParameterSpec(salt, ITERATIONS);
  
  // 5. Cipher 생성 및 초기화
  Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwoFish-CBC");
  cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
  
  // 6. 암호문 생성
  byte[] ciphertext = cipher.doFinal(plaintext.getBytes());
  
  // 7. salt와 암호문을 Base64 인코딩 후 결합하여 최종 결과물 생성
  String saltString = Base64.encodeToString(salt);
  String ciphertextString = Base64.encodeToString(ciphertext);
  
  return saltString+ciphertextString;
  
 }
 
 private static String decrypt(char[] password, String text) throws Exception {
  
  // 1. 8byte를 Base64인코딩하면 12byte가 생성된다.
  String salt = text.substring(0, 12);
  String ciphertext = text.substring(12, text.length());
  
  // 2. salt와 암호문을 Base64 디코딩하여 원래 상태로 되돌린다.
  byte[] saltArry = Base64.decodeToBytes(salt);
  byte[] ciphertextArry = Base64.decodeToBytes(ciphertext);
  
  // 3. 패스워드를 이용하여 PBEKeySpec 생성
  PBEKeySpec keySpec = new PBEKeySpec(password);
  SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHAAndTwoFish-CBC");
  
  // 4. 비밀 키 생성
  SecretKey key = keyFactory.generateSecret(keySpec);
  
  // 5. salt, iteration count를 위한 PBEParameterSpec 생성
  PBEParameterSpec paramSpec = new PBEParameterSpec(saltArry, ITERATIONS);
  
  // 6. Cipher 생성 및 초기화
  Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwoFish-CBC");
  cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
  
  // 7. 평문생성
  byte[] plaintextArry = cipher.doFinal(ciphertextArry);
  
  return new String(plaintextArry);
 }

}

Posted by sinpk

JCA & JCE

     설명

가)    JCA Runtime enviroment의 일부

나)  JCE JDK에 들어 있지 않은 JCA의 확장팩

나)    JDK JCA에 정의된 특정한 암호 함수만 사용 가능

 

     JCA

가)    전자 서명과 메시지 다이제스트 같은 기능에 대한 일반적인 API 제공

 

나)    주요 클래스들

     MessageDigest

     Signature

     KeyPaireGenerator

     KeyFactory

     CertificateFactory

     KeyStore

     AlgorithmParameters

     AlgorithmParameterGenerator

     SecureRandom

 

다)    암호 서비스 제공자 Sun Provider(Java 2 기준, sun.security.provider.Sun)

     MD5 메시지 다이제스트

     SHA-1 메시지 다이제스트

     DSA 전자 서명 사인과 검증

     DSA 키 쌍 생성

     DSA 키 변환

     X.509 인증서 생성

     Proprietary keystore 구현

     DSA 알고리즘 매개변수

     DSA 알고리즘 매개변수 생성

 

라)    암호 서비스 제공자 RSAJAC provider(com.sun.rsajca.Provider)

     RSA 키 쌍 생성

     RSA 키 변환

     SHA-1 또는 MD5 메시지 다이제스트를 이용한 RSA 서명

 

마)    JCA 접근

 MessageDigest myMessageDigest = MessageDigest.getInstance(“MD5”);

myMessageDigest.update(myData);

byte[] signatureBytes = myMessageDigest.digest();

 

 

     JCE(javax.crypto)

가)    주요 클래스와 인터페이스

     Cipher

     KeyAgreement

     KeyGenerator

     Mac

     SecretKey

     SecretKeyFactory

 

나)    JCE 접근 

KeyGenerator keyGenerator = KeyGenerator.getInstance(“Blowfish”);

Key key = keyGenerator.generatorKey();

Cipher cipher = Cipher.getInstance(“Blowfish/ECB/PKCS5Padding”);

cipher.init(Cipher.ENCRYPT_MODE, key);

byte[] cipherText = cipher.doFinal(myData);

  

다)    JCE 설치

이름

BouncyCastle

URL

http://www.bouncycastle.org

라이선스

오픈소스

참고문서

http://www.bouncycastle.org/docs/docs1.6/index.html

 

 

보통 썬의 JCE를 사용하기를 원하지만 일단 Sun JCE가 설치되고 나면 다른 것을 사용하지 못한다. Sun JCE DES, TripleDEs, Blowfish, Difie-Hellman외에는 사용할 수가 없다. 따라서 Bouncy Castle를 추천한다.

 

라)    Bouncy Castle 설치 (http://id0min.tistory.com/125 참조함)

     http://www.bouncycastle.org/latest_releases.html에서 자신의 JDK 버전에 해당되는 최신 버전을 다운로드 받는다. 다운받은 파일을 JDK JRE가 설치된 폴더에서 jre/lib/ext에 저장한다.

     양쪽 폴더에서 jre/lib/security 폴더에 있는 java.security 파일을 다음과 같이 수정한다. 숫자 10 provider 순서에 따라 수정한다.

security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

     unrestricted policy 파일들을 다운로드 받아  양쪽 폴더에서 jre/lib/security 폴더에 local_policy.jar US_export_policy.jar 파일을 교체한다. 아래 URL에서 파일을 다운로드 받아서 풀어보면 위의 2개 파일 있다. 덮어 씌우면 된다.

     설치한 후에 동작하는지 검증한다.

 

       마)    테스트 소스

 public static void main(String[] args) {

String providerName = "BC";

KeyGenerator keyGenerator = null;

if(Security.getProvider(providerName) == null)

System.out.println(providerName + " provider not installed");

else

       System.out.println(providerName + " is installed");

// Blowfish 블록 암호화 방식

System.out.println("Attepting to get a Blowfish key...");

try {

keyGenerator = KeyGenerator.getInstance("Blowfish");

} catch (NoSuchAlgorithmException e) {

}

keyGenerator.init(128);

SecretKey key = keyGenerator.generateKey();

System.out.println("OK");

//암호화 한다

            

System.out.println("Attempting to get a Cipher and encrypt...");

Cipher cipher = null;

byte[] ciphertext = null;

try {

       cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");

} catch (NoSuchAlgorithmException e) {}

catch (NoSuchPaddingException e) {}

try {

       cipher.init(Cipher.ENCRYPT_MODE, key);

} catch (InvalidKeyException e) {}

try {

       ciphertext = cipher.doFinal("This is a test".getBytes("UTF8"));

} catch (IllegalBlockSizeException e) {}

catch (BadPaddingException e) {}

catch (UnsupportedEncodingException e) {}

System.out.println("OK");

System.out.println("Test completed successfully : " + ciphertext);

}

 

 

Posted by sinpk

도구 > 환경설정 > 데이터베이스 > NLS

기본이 RR/MM/DD -> 변경 RR/MM/DD HH24:MI:SS

'소프트웨어 > Oracle' 카테고리의 다른 글

디비링크  (0) 2013.11.06
DB에서 java Vo 멤버 추출  (0) 2013.10.02
OVER()함수  (0) 2013.08.27
일련번호 채번  (0) 2013.08.07
Toad 단축키  (0) 2013.08.05
Posted by sinpk

OVER()함수

2013. 8. 27. 18:28 : 소프트웨어/Oracle

COUNT(*) OVER() : 전체행 카운트

COUNT(*) OVER()(PARTITION BY 컬럼) : 그룹단위로 나누어 카운트

 

MAX(*) OVER() : 전체행 중에 최고값

MAX(*) OVER()(PARTITION BY 컬럼) : 그룹내 최고값

 

MIN(*) OVER() : 전체행 중에 최소값

MIN(*) OVER()(PARTITION BY 컬럼) : 그룹내 최소값

 

SUM(*) OVER() : 전체행 합

SUM(*) OVER()(PARTITION BY 컬럼) : 그룹내 합

 

AVG(*) OVER() : 전체행 평균

AVG(*) OVER()(PARTITION BY 컬럼) : 그룹내 평균

 

STDDEV(*) OVER() : 전체행 표준편차

STDDEV(*) OVER()(PARTITION BY 컬럼) : 그룹내 표준편차

 

RATIO_TO_REPORT(*) OVER() : 전체행 값/SUM(전체행값) 퍼센테이지로 나타낼경우 100곱하면 됩니다.

RATIO_TO_REPORT(*) OVER()(PARTITION BY 컬럼) : 현재행 값/ SUM(그룹행값) 퍼센테이지로 나타낼경우 100곱하면 됩니다.

Posted by sinpk

심각: Error starting static Resources

java.lang.IllegalArgumentException: Document base /home/pay/apache-tomcat-7.0.42/webapps_test does not exist or is not a readable directory


  • tomcat_home/conf/Catalina/localhost/ 경로에 보면 xml파일이 있는데 이 중에서 에러메시지에 나온 디렉토리를 설정해놓은 xml파일을 삭제 하면 된다.


'소프트웨어 > WS/WAS' 카테고리의 다른 글

APR, AJP  (0) 2014.06.09
세션 클러스터링  (0) 2013.08.12
톰캣 성능 튜닝  (0) 2013.08.08
톰캣7을 통한 war 디플로이  (0) 2013.08.08
톰캣에서 날짜별 로그로 설정하는방법  (0) 2013.07.26
Posted by sinpk