티스토리 뷰
출처 :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;
}
'Skill > spring' 카테고리의 다른 글
Spring Boot Interceptor 설정 (0) | 2020.09.02 |
---|---|
Spring boot Interceptor (0) | 2020.09.02 |
[tomcat] http로 들어온 Request를 https로 Redirect (0) | 2020.07.27 |
[tomcat] 설치형 tomcat 설정 변경 (0) | 2020.07.23 |
[tomcat] 설정된 프로토콜 [Http11AprProtocol]이 가용하지 않은 APR/native 라이브러리를 요구합니다. (0) | 2020.07.23 |
- Total
- Today
- Yesterday
- 정규식
- element위치
- getter
- devtools
- PostgreSQL
- 프로젝트명변경
- $.each
- excel
- springboot
- setter
- Keycode
- spring
- @ExceptionHandler
- $.extend
- Javascript
- object key
- oracle
- 진열사랑
- CSS
- JQuery
- lombok
- caniuse
- DatePicker
- ul li로 테이블
- sumifs
- border-collapse
- draw.io
- 전후방탐색
- 여러 컬럼 update
- QueryDSL
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |