web developer

[java] SHA-256 암호화 [단방향] 본문

Language/Java

[java] SHA-256 암호화 [단방향]

trueman 2024. 7. 23. 15:51
728x90
728x90

SHA-256 (Secure Hash Algorithm 256-bit)


  1. 해시 함수:
    • SHA-256은 암호화 해시 함수입니다. 이는 데이터를 고정된 크기의 해시 값(256비트)으로 변환합니다.
    • 입력 데이터의 크기와 상관없이 항상 256비트의 해시 값을 출력합니다.
  2. 목적:
    • 데이터 무결성 확인을 위해 사용됩니다. 입력 데이터가 변경되면 해시 값도 완전히 달라지므로, 데이터의 변경 여부를 쉽게 감지할 수 있습니다.
    • 비밀번호 저장 시 해시 값을 사용하여 비밀번호 자체를 저장하지 않고도 인증을 수행할 수 있습니다.
    • 디지털 서명과 인증서에서 데이터의 무결성을 보장하기 위해 사용됩니다.
  3. 작동 방식:
    • 입력 데이터를 처리하여 고정된 256비트 길이의 해시 값을 생성합니다.
    • 동일한 입력은 항상 동일한 해시 값을 출력하지만, 입력 데이터의 작은 변화도 완전히 다른 해시 값을 생성합니다.

1. SHA-256 암호화 [salt 제외] - 예제

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA256Util {
    public static String getSHA256Hash(String data) {
        try {
            // MessageDigest 인스턴스를 SHA-256 알고리즘으로 초기화
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            
            // 데이터의 바이트 배열을 얻음
            byte[] byteData = data.getBytes();
            
            // 해시 값을 계산
            byte[] hashBytes = digest.digest(byteData);
            
            // 바이트 배열을 16진수 문자열로 변환
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            
            return hexString.toString().toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}
public class Main {
    public static void main(String[] args) {
        String data = "Hello, world!";
        
        // SHA256Util 클래스의 getSHA256Hash 메소드 호출
        String hash = SHA256Util.getSHA256Hash(data);
        
        System.out.println("SHA-256 해시 값: " + hash);
    }
}

2. SHA-256 암호화 [salt 포함] - 예제

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class SHA256Util {

    // SHA-256 해시 값을 계산하는 메소드
    public static String getSHA256Hash(String data, byte[] salt) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(salt);  // Salt 추가
            byte[] byteData = data.getBytes();
            byte[] hashBytes = digest.digest(byteData);
            
            return bytesToHex(hashBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    // Salt를 생성하는 메소드
    public static byte[] generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16]; // 16바이트의 Salt
        random.nextBytes(salt);
        return salt;
    }

    // 바이트 배열을 16진수 문자열로 변환하는 메소드
    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString().toUpperCase();
    }
}
public class SHA256Example {
    public static void main(String[] args) {
        String password = "mySecurePassword";
        
        // Salt 생성
        byte[] salt = SHA256Util.generateSalt();
        
        // Salt와 비밀번호를 조합한 해시 값 계산
        String saltedHash = SHA256Util.getSHA256Hash(password, salt);
        
        System.out.println("Salt: " + SHA256Util.bytesToHex(salt));
        System.out.println("Salted SHA-256 해시 값: " + saltedHash);
    }
}

3. SHA-256 암호화 [salt 포함] - 로그인 예제

사용자가 로그인할 때 입력한 비밀번호를 확인하기 위해서는 절차는 다음과 같습니다.

  1. 저장된 Salt 및 해시 값을 DB에서 가져오기: 사용자가 로그인하려는 계정의 Salt와 해시 값을 DB에서 가져옵니다.
  2. 입력한 비밀번호에 같은 Salt를 적용하여 해시 값 생성: 로그인 시 입력한 비밀번호와 저장된 Salt를 사용하여 SHA-256 해시 값을 생성합니다.
  3. 생성된 해시 값과 저장된 해시 값을 비교: 생성된 해시 값이 저장된 해시 값과 일치하는지 확인합니다.
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class SHA256Util {

    // SHA-256 해시 값을 계산하는 메소드
    public static String getSHA256Hash(String data, byte[] salt) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(salt);  // Salt 추가
            byte[] byteData = data.getBytes();
            byte[] hashBytes = digest.digest(byteData);
            
            return bytesToHex(hashBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    // Salt를 생성하는 메소드
    public static byte[] generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16]; // 16바이트의 Salt
        random.nextBytes(salt);
        return salt;
    }

    // 바이트 배열을 16진수 문자열로 변환하는 메소드
    public static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString().toUpperCase();
    }

    // 16진수 문자열을 바이트 배열로 변환하는 메소드
    public static byte[] hexToBytes(String hex) {
        int length = hex.length();
        byte[] bytes = new byte[length / 2];
        for (int i = 0; i < length; i += 2) {
            bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                                 + Character.digit(hex.charAt(i + 1), 16));
        }
        return bytes;
    }
}

 

public class LoginService {

    // 사용자의 로그인 시 비밀번호 확인 메소드
    public static boolean verifyPassword(String enteredPassword, String storedHash, String storedSalt) {
        // 저장된 Salt를 바이트 배열로 변환
        byte[] saltBytes = SHA256Util.hexToBytes(storedSalt);
        
        // 입력한 비밀번호와 Salt를 사용하여 해시 값 계산
        String enteredHash = SHA256Util.getSHA256Hash(enteredPassword, saltBytes);
        
        // 저장된 해시 값과 비교
        return enteredHash.equals(storedHash);
    }

    public static void main(String[] args) {
        // 예제 데이터 (DB에 저장된 값이라고 가정)
        String storedHash = "e9e6b0f8f97f20d65d6069d55f094fdc33190c603c8b5d5c57c60d64f4a7e4e8"; // 예제 해시 값
        String storedSalt = "a3f4c2d4e5b67891a0cdef23456789ab"; // 예제 Salt 값
        
        // 사용자가 입력한 비밀번호
        String enteredPassword = "mySecurePassword";

        // 비밀번호 검증
        boolean isPasswordCorrect = verifyPassword(enteredPassword, storedHash, storedSalt);

        if (isPasswordCorrect) {
            System.out.println("비밀번호가 일치합니다.");
        } else {
            System.out.println("비밀번호가 일치하지 않습니다.");
        }
    }
}

SHA-256 암호화 [+salt]
https://study-easy-coding.tistory.com/153

 

[암호화] 양방향 vs 단방향 암호화 feat. SHA256

서비스하는 어떤 회사든, 토이 프로젝트든 로그인/회원가입이 필수적으로 들어간다. 고객 데이터를 통해 맞춤형 정보를 보여주고, 지표를 통한 다양한 마케팅 방식으로 활용할 수 있기 때문이

study-easy-coding.tistory.com

SHA-256 암호화 [+salt]

https://padosol.tistory.com/50 

 

[Java] SHA-256 암호화 & Salt ( 적용예시 )

SHA-256 이란? SHA-256은 SHA(Secure Hash Algorithm) 단방향 알고리즘의 한 종류로, 해시 값을 이용한 암호화 방식 중 하나이다. 256비트로 구성되며 64자리 문자열을 반환한다. 여기서 단방향 알고리즘이란

padosol.tistory.com

SHA-256 암호화

https://m.blog.naver.com/doksg/221811748218

 

Hash 함수와 SHA256 (1)

Hash funciton이라는 게 있습니다. 다양한 길이의 input을 받아서 정해진 길이의 output을 출력하는 함수...

blog.naver.com

 

728x90
728x90