티스토리 뷰

Skill/spring

[java] 암호화 + salt

진열사랑 2020. 8. 18. 18:24

출처 :gt1000.tistory.com/entry/비밀번호-암호화-PBKDF2

 

1. 해시 함수

 1) 정의
  - 임의의 크기를 가진 데이터를 입력 받아서 고정된 크기의 결과값을 출력하는 함수로
    메시지 다이제스트(Message Digest)라고도 함. 메시지의 축약을 의미함.
  - 고정된 크기의 결과값을 가지고 있으므로 출력할수 있는 값은 한정될수 밖에 없음
  - 1Byte 의 해시값을 생성하는 함수라면 2의 8승, 256개의 해시값
    SHA256 의 경우 256비트, 32Byte 2의 32승의 경우의 수를 가짐
  - 입력할수 있는 값은 무난히 많으므로 입력값은 다르지만 출력값이 같아지는 경우가 존재할 수 밖에 없음
  - 같은 입력에 대해서는 항상 같은 출력이 나오므로 입력한 데이터에 대한 지문을 생성함으로써
    오류 변조를 탐지할수 있는 무결성을 제공. 암호학적 의사 난수를 만들어 키를 생성하거나
    전자서명에서 메시지를 축약할 때 사용
 3) 해시 함수의 조건
  - 역상 저항성(preimage resistance) : 단방향 함수. 입력값을 알면 해시값을 구하기 쉽지만
    해시값을 알아도 입력값은 구할수 없어야 함.
  - 제 2 역상 저항성(second preimage resistance) : 입력값으로 구한 해시값과 동일한 해시값을
    가진 다른 입력값을 찾을 수 없어야 함. 즉 해시값에 영향을 주지 않으면서 입력값을 변경할 수 없어야 함.
  - 충돌 저항성(collision resistance) : 충돌에 대해 안전해야 함. 완벽한 충볼 회피란 있을 수
    없지만 같은 해시값을 생성하는 두개의 입력값을 찾을 수 없어야 함
   
2. 패스워드 해킹 방법
 1) 공격 대상 사이트에 더미 유저 등록
  - test1 : 1234          60abdi448jj549320230(패스워드 해시값)
    test2 : 12345678      74300340kdkfdlklrdlr(패스워드 해시값)
    test3 : asdf6254      7jfoero3443kkkfdkfkf(패스워드 해시값)

 

 2) 유저 DB 내용 반출
  - SQL 인젝션 공격 등
 3) 1)에서 등록한 패스워드와 같은 해시값을 패스워드로 같는 사용자를 조사
  - saburo :              60abdi448jj549320230(패스워드 해시값)
    saburo 의 비밀번호는 1234 임

3. MessageDigest 클래스
 1) 정의
  - 암호학적으로 안전한 해시값을 생성하는 기능을 제공하고 SHA-1, MD5 같은 다양한 해시 알고리즘을 제공

 

 2) 메소드
  - public static MessageDigest getInstance(String algorithm) : 주어진 알고리즘에 대한 인스턴스 생성
  - pulbic static MessageDigest getInstance(String algorithm, String provider) : 주어진 프로바이더로부터
    알고리즘에 해당하는 인스턴스를 생성

  - public void update(byte[] input) : 해시값을 생성할 데이터를 입력
  - public byte[] digest() : 해시값을 생성
  - public byte[] digest(byte[] input) : 데이터를 입력한 후 해시값을 생성   

 

4. 대책
 1) 솔트
  - 해시의 원래 데이터에 추가하는 문자열. 솔트에 의해 보이는 패스워드를 길게 하는 것과 함께 솔트를
    유저마다 다른 것으로 하면 패스워드가 같더라도 다른 해시값을 생성할수 있음.

    update 메소드 내부에서 engineUpdate(input, 0, input.length); 를 호출함으로서 원래 데이터에
    추가하는 형태가 되는거 같음.

 2) 스트레칭
  - 솔트를 사용해도 무작위 공격의 위험성은 남아 잇음. 솔트를 사용해도 해시의 계산 시간은 그다지 변하지 않음
    무작위 공격에 대항하기 위해서는 해시 계산의 속도를 늦출 필요가 있음
  - 해시의 계산을 반복하게 하여 계산 시간을 늦추는 방법
  - 서버 부담의 단점이 있으므로 최적화가 필요.

 

5. 소스

/**
 * 비밀번호 생성
 * @param password 평문 비밀번호
 * @param salt
 * @return
 * @throws Exception
 */
public static String getPassword(String password, String salt) {
    String encriptPassword = "";
    try {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
        digest.update(salt.getBytes());
        byte[] input = digest.digest(password.getBytes("UTF-8"));
        for (int i = 0; i < ITERATION_NUMBER; i++) {
            digest.reset();
            input = digest.digest(input);
        }
       
        BASE64Encoder endecoder = new BASE64Encoder();
        encriptPassword = endecoder.encode(input);
    } catch(Exception e) {
        e.printStackTrace();
    }
    return encriptPassword;
}
   
/**
 * SALT 생성
 * @return
 * @throws NoSuchAlgorithmException
 */
public static String getSalt() {
    String value = "";
    try {
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        // Salt generation 128 bits long
        byte[] salt = new byte[16];
        secureRandom.nextBytes(salt);
        value = salt.toString();
    } catch(Exception e) {
        e.printStackTrace();
    }
    return value;
}

참고 : https://howtodoinjava.com/java/java-security/how-to-generate-secure-password-hash-md5-sha-pbkdf2-bcrypt-examples/

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함