2020. 12. 23. 14:32ㆍ2021/JOB DA STUDY
특정 데이터를 암호화 하여 DB에 보관해야하는 경우가 있다.
이때 암호화 및 파일 무결성 검사의 용도로 MD5와 SHA-256를 이용한다.
1. java.security.MessageDigest Class
이 클래스에는 MD5, SHA-1, SHA-256 등이 있다.
MessageDigest.getInstance(String 알고리즘)
-> 해당 알고리즘에서 해시값을 계산하는 MessageDigest를 구할 수 있다.
2. MD5(Massage -Diget 알고리즘 5
- 메시지 축약 알고리즘으로 보안보다 어떤 공백, 점 하나만 들어와도 해시값이 달라져 파일 무결성이 위배 되었음을 찾는데 더 많이 이용
- 128bit의 해쉬를 제공하며, 암호화/복호화를 통해 보안용으로도 많이 사용하지만 암호화 결함의 발견으로 보안의 용도로는 SHA와 같은 다른 알고리즘을 많이 이용
private String getMD5HashString(String inputTxt) {
String MD5 = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5"); <- (1)
md.update(inputTxt.getBytes()); <- (2)
byte byteData[] = md.digest(); <- (3)
StringBuffer sb = new StringBuffer(); <- (4)
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)); <- (5)
}
MD5 = sb.toString(); <- (6)
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
MD5 = null;
}
return MD5;
}
}
(1). MessageDigest md = MessageDigest.getInstance("MD5");
- Singleton
자바 프로그램이 동작 할 때 최초의 한번만 메모리를 할당하고, 할당된 메모리에서만 사용하는 방식
고정된 메모리 영역을 사용함으로써 메모리의 낭비를 줄이고, 공통된 객체를 사용하는 경우에는 객체를 더 이상 새롭게 만들지 않아도 된다.
- getInstance()
싱글톤패턴으로 단 한번만 인스턴스를 생성한 후에 그 객체로 계속 공유
(파라미터로 MD5, SHA-256, SHA512 등이 들어가면, 이에 대한 다이제스트 오브젝트 생성)
(2). md.update(inputTxt.getBytes));
- .update
MessageDIgest 클래스의 update() 메소드는 호출 될 때마다 객체 내에 저장된 digest 값이 계속해서 갱신된다.
- .getBytes
사람들이 알아 볼 수 있는 String 타입을 1 과 0으로 이루어진 Bytes타입으로 변환한다.
(보통은 DB가 한글을 지원하지 않는 경우 한글로 된 문자를 숫자로 인코딩하여 DB에 저장하기 위해 사용한다.)
(3). byte byteDate[] = md.digest();
- .digest
바이트 배열로 해쉬를 반환하는데 padding등의 최종 처리로 해시 계산을 완료한다.
따라서 update한 값을 digest를 호출함으로써 가져올 수 있다.
(4). StringBuffer sb = new StringBuffer();
- StringBuffer
StringBuffer는 문자열을 추가하거나 변경하는 경우에 주로 사용하는 자료형이다.
public class Test {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("hello");
sb.append(" ");
sb.append("jump to java");
System.out.println(sb.toString());
}
}
public class Test {
public static void main(String[] args) {
String temp = "";
temp += "hello";
temp += " ";
temp += "jump to java";
System.out.println(temp);
}
}
- StringBuffer의 경우에는 객체가 단 한번만 생성되면 그뒤에 문자열은 계속 그 객체에 append된다. 하지만 String 자료형은 +연산이 있을때 마다 새로운 Stirng 객체가 생성된다.
->첫번째 예제의 경우에는 sb라는 객체 1개만 생성이 되지만, 두번째 예제의 경우에는 총 4개의 객체가 생성된다.
- String 자료형은 한번 값을 생성하면 변경할 수 없다. (immutable) trim, toUpperCase등의 메소드의 경우 문자열이 변경된것 처럼 보이지만, 이는 다른 String객체를 생성해 리턴한 것이다. 하지만 StringBuffer의 경우에는 값의 변경이 가능하다. (mutable)
- StringBuffer는 String 자료형보다 무거운 편이어서 new StringBuffer()를 생성하는 것은 일단 String을 사용하는 것 보다 메모리 사용량이 많고, 속도도 느리다. 따라서 문자열의 추가, 변경 등의 작업이 많은 경우에는 StringBuffer를 사용하며, 변경이 잦지 않은 경우에는 String을 이용한다.
(5). sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
바이트 배열을 16진수(HEX) 문자열로 변환
- (byteData[i] & 0xff) + 0x100
1. byteData[i] & 0xff
byte는 8bit의 공간을, int는 32bit의 공간을 차지하는데 비트연산자 &를 수행하는 경우 비트수가 낮은 byte가 비트수가 높은 int형에 맞춰 강제 형변환하게 된다. (byte: 8bit -> 32bit)
이때, byteDate[i]의 가장 앞의 비트가 0인 경우에는 0으로 채우지만, 1인 경우에는 비트 확장시 모든 비트를 1로 채운다.
1로 채우게 되면 원본의 값과는 완전 다른 값이 되기 때문에 이를 0을 바꾸어 주기 위해 "& 0xff" 연산을 수행한다.
(0xff: 00000000 00000000 00000000 11111111)
2. + 0x100
결론적으로는 이 연산을 하든지 하지 않든지 같은 값으로 나온다.
하지만 이를 하게 되면, Integer.toString(n, 15) 메소드의 결과값을 강제로 3자리로 만들어 준다.
10진수 | 16진수 | 16진수 ( +0x100 연산 NO) | 16진수 ( +0x100 연산 OK) |
1 | 1 | 1 | 101 |
2 | 2 | 2 | 102 |
3 | 3 | 3 | 103 |
4 | 4 | 4 | 104 |
5 | 5 | 5 | 105 |
10 | a | a | 10a |
11 | b | b | 10b |
12 | c | c | 10c |
16 | 10 | 10 | 110 |
- ((byteData[i] & 0xff) + 0x100, 16).substring(1))
1. .substring(1)
3자리 중에서 1이 들어오는 맨 앞자리는 제거된 01, 02, 03, 04, 05, 0a, 0b, 0c, 10 2자리 수만 추출이 된다.
3. SHA(Secure Hash Standard)
- 서로 관련된 암호학적 해시 함수들의 모임
- SHA-1이 가장 많이 사용되며, TLS, SSL, PGP, SSH, IPSec 등 많은 보안 프로토콜과 프로그램에서 사용
- MD5대신 SHA-1을 많이 사용하며, 좀 더 중요한 기술에는 SHA-256이나 그 이상의 알고리즘을 사용하는 것을 권장
'2021 > JOB DA STUDY' 카테고리의 다른 글
InputStream and OutputStream (0) | 2020.12.28 |
---|---|
3주차 과제: 연산자 (0) | 2020.12.27 |
Public과 Private (0) | 2020.12.22 |
Instanceof (0) | 2020.12.21 |
Argument 와 Parameter (0) | 2020.12.21 |