[블록체인] 블록체인 & 해시함수 실습

DAUN JO·2021년 6월 30일
0

TIL

목록 보기
2/17

해시함수

  • 해시 함수는 특정 입력을 고정 길이를 가진 임의의 해시값으로 바꿔주는 함수입니다.
  • 무한한 입력 대비 고정된 출력을 합니다. 따라서 해시 충돌이 발생 가능성이 항상 존재합니다.
  • 비트코인은 SHA256 해시 함수를 사용합니다.
  • SHA256 함수의 해시값은 256bit 길이를 가지므로 해시 충돌 가능성이 매우 낮습니다. 이러한 안정성 때문에 비트코인은 SHA256 함수를 사용합니다.

해시 함수 특징

SHA256 함수와 같은 암호학적 해시 함수는 아래 세 가지 유용한 성질을 가집니다.

  • collision-free : 해시 함수를 적용한 임의의 두 결과값이 같은 해시값을 같을 확률이 무시할 정도로 낮다.
  • hiding : 해시 함수의 결과값에서 입력값을 추정하기 어렵다.
  • puzzle-friendly : 해시값이 고정된 길이를 갖고 랜덤하게 해시값이 분포되는 점을 활용해 손쉽게 계산 문제를 만들 수 있다.

활용 사례

  1. DB에 비밀번호 저장하기
    가장 대표적으로 사용되는 것은 바로 비밀번호를 저장할 때, DB(database, 데이터베이스)에서는 해시함수로 암호화하여 저장을 하는 것이다. 이럴 경우 해커가 비밀번호를 탈취해도 해당 유저의 "진암호"를 알 수 없기 때문에 해당 유저로 접속을 할 수가 없다.

  2. 복제 문서 판별
    버전관리나 문서 복제등을 체크하기 위해서 해시함수를 사용하는 경우가 꽤 많다. 해시는 모든 문자열은 일정한 크기의 문자열로 변환하기 때문에 모든 단어를 비교하는 것보다 당연히 속도가 비약적으로 빠르다.

  3. 검색 용도
    문자를 숫자나 저장되는 주소로 치환하여 검색에 사용되는 예도 있다.

해시를 사용하는 자료구조

  1. 효율적인 데이터 관리
  • 적은 리소스로 많은 데이터를 효율적으로 관리
  • 예를 들어, 해시 함수로 HDD나 Cloud에 존재하는 무한에 가까운 데이터(키)들을 유한한 개수의 해시값으로 매핑함으로써 작은 크기의 캐시 메모리로도 프로세스를 관리할 수 있다.
  1. 빠른 데이터 처리
  • Index에 해시값으르 사용함으로써 모든 데이터를 살피지 않아도 검색과 삽입/삭제를 빠르게 할 수 있다.

Java로 간단한 블록체인 구현

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);
        }
    }
}

출처

https://needjarvis.tistory.com/239

https://yjshin.tistory.com/entry/%EC%95%94%ED%98%B8%ED%95%99-%ED%95%B4%EC%8B%9C-%ED%95%A8%EC%88%98-%EC%9E%91%EC%84%B1-%EC%A4%91

profile
🍕

0개의 댓글