java.security 라이브러리를 이용한 자바 암호화하기, 되새겨보려는 의도로 작성하는
포스팅이기때문에 설명이 충분하지 않을 수 있습니다.
요즘같은 개인정보 유출 사례가 많은시대에 암호화는 선택이 아닌 필수입니다.
참고자료를 보기위해 대학교 수업때사용했던 알기쉬운 정보보호개론 책을 다시 책장에서 끄집어냈습니다. ㅋㅋ
본문에 들어가기전 몇 교양으로 알고 넘어가야 할 기초 개념은 아래와 같습니다.
암호 : 해독 불가능한 형태로 변환 또는 변환된 암호를 해독 가능한 형태로 변환
평문(Plaintext) : 일반 텍스트, 즉 눈에 보이는 글자
암호문(Chphertext) : 해독 불가능한 텍스트
암호화(Encryption) : 평문을 암호문으로 변환
복호화(Decryption) : 암호문을 평문으로 변환
대칭키 암호화 알고리즘(비밀키) : 암호화키와 복호화키가 같다
비대칭키 암호화 알고리즘(공개키) : 암호화키와 복호화키가 서로 다르다
1. MD5
- MessageDigest 객체를 이용하여 알고리즘 타입을 "MD5"로 생성.
- 128bit 의 해시 값.
- 암호화 키가 없기때문에 역시 복호화 키도 없다. 패스워드 암호화 경우 복잡하게 하는것이 좋음.
- 서로 다른 값에 같은 해시가 발생하는 충돌 취약점이 발견되어 사용은 권장하지 않음.
2. SHA-256
- MessageDigest 객체를 이용하여 알고리즘 타입을 "SHA-256"로 생성.
- 256bit 의 해시 값.
- 암호화 키가 없기때문에 역시 복호화 키도 없다.
3. SHA-512
- MessageDigest 객체를 이용하여 알고리즘 타입을 "SHA-512"로 생성.
- 512bit 의 해시 값.
- 암호화 키가 없기때문에 역시 복호화 키도 없다.
public static String generateMD5(String message) { return hashString(message, "MD5","UTF-8"); } public static String generateSHA256(String message) { return hashString(message, "SHA-256","UTF-8"); } public static String generateSHA512(String message) { return hashString(message, "SHA-512","UTF-8" ); }
private static String hashString(String message, String algorithm, String charest) { try { MessageDigest digest = MessageDigest.getInstance(algorithm); byte[] hashedBytes = digest.digest(message.getBytes(charest));
return convertByteArrayToHexString(hashedBytes); } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { return ""; } }
private static String convertByteArrayToHexString(byte[] arrayBytes) { StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < arrayBytes.length; i++) { stringBuffer.append(Integer.toString((arrayBytes[i] & 0xff) + 0x100, 16).substring(1)); } return stringBuffer.toString(); } |
대칭키 알고리즘
복호화 키만 알고 있으면 암호화된 것을 복호화 할 수 있기때문에 유출되지 않도록 주의해야한다.
AES256 : 16자리의 암호화 키가 필요하며 16자리 이하일경우는 UnsupportedEncodingException 가 발생된다.
Cipher 객체에 존재하지 않는(오타) 알고리즘을 전달할 시 NoSuchAlgorithmException 가 발생되며
인코딩 타입력시 잘못 전달할 시 UnsupportedEncodingException 발생된다.
국내에서 지원하는 자바정책은 AES128 까지 이므로 jar 를 추가 해줘야 예외가 발생되지 않는다.
최신버젼은 메이븐에서 확인
import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.Key; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /** * 양방향 암호화 알고리즘인 AES256 암호화를 지원하는 클래스 */ public class AES256Util { private String iv; private Key keySpec;
public AES256Util() { // TODO Auto-generated constructor stub }
/** * 16자리의 키값을 입력하여 객체를 생성한다. * @param key 암/복호화를 위한 키값 * @throws UnsupportedEncodingException 키값의 길이가 16이하일 경우 발생 */ public AES256Util(String key) throws UnsupportedEncodingException { this.iv = key.substring(0, 16); byte[] keyBytes = new byte[16]; byte[] b = key.getBytes("UTF-8"); int len = b.length; if(len > keyBytes.length){ len = keyBytes.length; } System.arraycopy(b, 0, keyBytes, 0, len); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); this.keySpec = keySpec; } /** * AES256 으로 암호화 한다. * @param str 암호화할 문자열 * @return * @throws NoSuchAlgorithmException * @throws GeneralSecurityException * @throws UnsupportedEncodingException */ public String encrypt(String str) throws NoSuchAlgorithmException, GeneralSecurityException, UnsupportedEncodingException{ Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv.getBytes())); byte[] encrypted = c.doFinal(str.getBytes("UTF-144")); String enStr = new String(Base64.encodeBase64(encrypted)); return enStr; } /** * AES256으로 암호화된 txt 를 복호화한다. * @param str 복호화할 문자열 * @return * @throws NoSuchAlgorithmException * @throws GeneralSecurityException * @throws UnsupportedEncodingException */ public String decrypt(String str) throws NoSuchAlgorithmException, GeneralSecurityException, UnsupportedEncodingException { Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv.getBytes())); byte[] byteStr = Base64.decodeBase64(str.getBytes()); return new String(c.doFinal(byteStr), "UTF-8"); } } |
* SHA256을 사용할 경우 발생할 수 있는 문제점에 대한 글 : 네이버 D2 블로그 "안전한 패스워드 저장" 바로가기
'백앤드 이야기 > JAVA&Spring' 카테고리의 다른 글
[JAVA] String, StringBuilder, StringBuffer의 차이 (0) | 2020.02.10 |
---|---|
[Spring] spring profile 및 logback-spring.xml 을 이용한 log 관리 (0) | 2019.10.21 |
[JAVA] 인코딩과 인코딩 방식 (0) | 2019.09.09 |
[JAVA] 하드디스크 드라이브 용량 확인 (0) | 2019.08.05 |
[JAVA] Paging 모델 및 소스 (Mybatis) (0) | 2019.07.07 |
댓글