SHA256 함수와 같은 암호학적 해시 함수는 아래 세 가지 유용한 성질을 가집니다.
DB에 비밀번호 저장하기
가장 대표적으로 사용되는 것은 바로 비밀번호를 저장할 때, DB(database, 데이터베이스)에서는 해시함수로 암호화하여 저장을 하는 것이다. 이럴 경우 해커가 비밀번호를 탈취해도 해당 유저의 "진암호"를 알 수 없기 때문에 해당 유저로 접속을 할 수가 없다.
복제 문서 판별
버전관리나 문서 복제등을 체크하기 위해서 해시함수를 사용하는 경우가 꽤 많다. 해시는 모든 문자열은 일정한 크기의 문자열로 변환하기 때문에 모든 단어를 비교하는 것보다 당연히 속도가 비약적으로 빠르다.
검색 용도
문자를 숫자나 저장되는 주소로 치환하여 검색에 사용되는 예도 있다.
import java.security.MessageDigest;
public class BlockChainTest {
public static void main(String[] args) {
Block genesis = genesisBlock("Genesis Block");
Block two = addBlock(genesis.hash, "2nd");
Block three = addBlock(two.hash, "3rd");
Block four = addBlock(two.hash, "4th");
}
//블록을 생성하는 메소드
private static Block genesisBlock(String data) {
Block block = new Block("", data);
//Genesis 블록 생성
block.genesisHash();
//블록이 생성될 때마다 블록 내용 출력
block.print();
return block;
}
private static Block addBlock(String prevHash, String data) {
Block block = new Block(prevHash, data);
block.hash();
block.print();
return block;
}
//sha256로 해시 처리를 도와주는 메소드
public static String encrypt(String pwd) {
StringBuffer hexString = new StringBuffer();
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(pwd.getBytes("UTF-8"));
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
return hexString.toString();
}
//최초의 블록을 제외한 블록의 경우는 nonce를 증가시키며 해시값의 시작이 00000일때까지 해시 알고리즘을 반복
static class Block{
private String prevHash;
private String data;
private int nonce;
private String hash;
public Block(String prevHash, String data) {
super();
this.prevHash = prevHash;
this.data = data;
}
public void genesisHash() {
hash = encrypt(prevHash + data + nonce);
}
public void hash() {
String tmp = "";
while (true) {
tmp = encrypt(prevHash + data + nonce);
//해시 값은 앞에 0이 5개인 경우만 통과
if(tmp.substring(0, 5).equals("00000")) {
hash = tmp;
break;
}else {
nonce++;
}
}
}
@Override
public String toString() {
return "Block [prevHash=" + prevHash + ", data=" + data + ", nonce=" + nonce + ", hash=" + hash + "]";
}
public void print() {
System.out.println("nonce: " + nonce);
System.out.println("data: " + data);
System.out.println("prevHash: " + prevHash);
System.out.println("hash: " + hash);
}
}
}