SHA-256 와 SHA-512 와 RSA방식을 가장 많이 쓴다.
MDS는 나온지 너무 오래되서 취약하다. 뽐뿌가 이거쓰다가 털렸다.
SHA-256을 실습해보자
1. USERS 테이블에 SALT 컬럼을 추가해보자
2. 회원 비밀번호를 SALT를 사용한 SHA-256으로 암호화 하자
SHA-256은 64 자리 문자열이 출력된다.
sha256은 hash 함수의 일종이다
hash 함수라는게 뭐냐면 다 알고 있겠지만 간단히 설명해보겠다
y = x + 2 이런 함수는 y를 알면 x도 알 수 있다
하지만 y = hash(x) 이런 해쉬 함수는 y를 알아도 x를 알 수 없는게 특징이다
그리고 모든 x값에 대해 각기 다른 y값을 내뱉는 특징 때문에 x가 원본임을 증명하는 일종의 시그니쳐로도 사용할 수 있다
(정확하게 말하자면 hash 함수는 단사함수가 아니다. hash collision이 있어서 다른 x임에도 같은 y값이 나오는 경우도 있다.
hash collision을 피하기 위해선 계산을 더 복잡하게 하면 된다. 적당한 기회 비용을 두고 밀당을 해야한다는 소리)
hash 결과값은 32bit 8개를 병렬로 늘어놓은 값
32bit x 8 = 256bit 그래서 이름이 sha256이다
비밀번호에 랜덤 값을 주고 또 암호화를 시킨다.
1 2 3 4 5 6 7 8 9 | // 회원가입시 비밀번호를 SHA-256 으로 SALT 이용해 암호화 하기 String salt = SHA256Util.generateSalt(); String newPassword = SHA256Util.getEncrypt(memberVO.getUserPassword(), salt); memberVO.setUserPassword(newPassword); memberVO.setSalt(salt); memberService.addMember(memberVO); SendMessage.send(response, "OK"); | cs |
로그인 할때 멤버별 salt로 input 값을 암호화를 시킨뒤 db에 저장된 값과 맞는지 비교하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public boolean login(HttpSession session, LoginVO loginVO) { String memberSalt = memberDAO.getSaltById( loginVO.getId()); String inputPassword = loginVO.getPassword(); String newPassword = SHA256Util.getEncrypt(inputPassword, memberSalt); MemberVO memberVO = memberDAO.login(loginVO); if(memberVO != null) { // 로그인 성공시.. LoginStore loginStore = LoginStore.getInstance(); if ( loginStore.get(loginVO.getId())!= null ){ loginStore.logout(loginVO.getId()); } session.setAttribute(Session.MEMBER, memberVO); loginStore.add(loginVO.getId(), session); session.setAttribute(Session.MEMBER, memberVO); } return memberVO != null; } | cs |
그러면 회원 DB에 암호화 되서 저장된 data ↓
SHA256Util.java
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package kr.co.hucloud.utilities; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; /** * SHA-256 암호화 * * @author Minchang Jang * */ public class SHA256Util { public static String getEncrypt(String source, String salt) { return getEncrypt(source, salt.getBytes()); } public static String getEncrypt(String source, byte[] salt) { String result = ""; byte[] a = source.getBytes(); byte[] bytes = new byte[a.length + salt.length]; System.arraycopy(a, 0, bytes, 0, a.length); System.arraycopy(salt, 0, bytes, a.length, salt.length); try { MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(bytes); byte[] byteData = md.digest(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < byteData.length; i++) { sb.append(Integer.toString((byteData[i] & 0xFF) + 256, 16).substring(1)); } result = sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return result; } public static String generateSalt() { Random random = new Random(); byte[] salt = new byte[8]; random.nextBytes(salt); StringBuffer sb = new StringBuffer(); for (int i = 0; i < salt.length; i++) { // byte 값을 Hex 값으로 바꾸기. sb.append(String.format("%02x",salt[i])); } return sb.toString(); } } | cs |
참고
레퍼런스 문서
http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
'CS > Secure' 카테고리의 다른 글
[Clean Coding] JUnit (0) | 2016.04.29 |
---|---|
[Clean Coding] 주의깊은 코드 SOLID (0) | 2016.04.29 |
[Secure Coding] 해킹방지 코드짜기 (0) | 2016.04.27 |
[Secure Coding] Paros 64비트에서 실행 (4) | 2016.04.27 |
[Secure Coding] 예시 보기 CWE CVE CWE/SANS TOP 25 (0) | 2016.04.26 |