2014. 8. 7. 21:07 java
비밀번호 암호화 SHA256, Salt
이거보다는 Spring Security를 이용하길 바란다.
링크 참조
1 해시 함수 SHA256설명.txt
1) 정의
- 임의의 크기를 가진 데이터를 입력 받아서 고정된 크기의 결과값을 출력하는 함수로
메시지 다이제스트(Message Digest)라고도 함. 메시지의 축약을 의미함.
- 고정된 크기의 결과값을 가지고 있으므로 출력할수 있는 값은 한정될수 밖에 없음
- 1Byte 의 해시값을 생성하는 함수라면 2의 8승, 256개의 해시값
SHA256 의 경우 256비트, 32Byte 2의 32승의 경우의 수를 가짐
- 입력할수 있는 값은 무난히 많으므로 입력값은 다르지만 출력값이 같아지는 경우가 존재할 수 밖에 없음
- 같은 입력에 대해서는 항상 같은 출력이 나오므로 입력한 데이터에 대한 지문을 생성함으로써
오류 변조를 탐지할수 있는 무결성을 제공. 암호학적 의사 난수를 만들어 키를 생성하거나
전자서명에서 메시지를 축약할 때 사용
2) 예제
- 김문수 : 01, 강대권 : 06, 이수훈 : 08
메시지 해시함수 해시값
00
김문수 1 .............. 처리 ..............> 1 01
강대권 2 .............. 처리 .......... 02
이수훈 3 .............. 처리 .............. 03
. . 04
. . 05
........> 2 06
. 07
.....> 3 08
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 소스
1) 예제(https://www.owasp.org/index.php/Hashing_Java)
/**
* 비밀번호 생성
* @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;
}
비밀번호 암호화 할때 SHA2(비밀번호 + SALT)와 어떻게 다른지 봐야 할거 같다.
PBKDF2 나 bcrypt 가장 낫다고 한다.
[소스파일]
'java' 카테고리의 다른 글
JWT(JSON Web Token) (0) | 2014.10.17 |
---|---|
PMD로 배우는 올바른 자바 코딩 방법 (0) | 2014.09.16 |
보안 인증 관련 (0) | 2013.03.19 |
암호화 솔트 salt (0) | 2013.03.19 |
인증 (0) | 2013.03.19 |