Custom Password Encrypt 구현

개나뇽·2025년 1월 2일

비밀번호란?

  • 이용자가 시스템에 대한 접근 권한을 가지고 있음을 증명하는 암호 문자.
  • 특정 사용자에 대한 본인 인증성 문자.
  • ID, 닉네임과는 다르게 겉으로 표기되지 않고 감추어지며 오로지 해당 사용자만 알고 있어야 함.

비밀번호 저장

위 에서 말했듯이 비밀번호는 노출 및 유출 시 사용자에게 큰 피해가 갈 수 있어 절대적으로 막아야한다.

문제점

  • 비밀번호는 평문으로 저장하면 안된다.
    • DB가 탈취되면 모두 노출 될 수 있음
    • DB를 활용하는 개발자 또한 개인 정보 조회 가능.

해결 방안

  • 민감한 개인 정보를 알아보지 못하거나 알아도 사용할 수 없게 만들어야 함. → 암호화

비밀번호 암호화

암호화란 암호키와 알고리즘 기반으로 평문을 암호문으로 재구성하여 무결성 및 기밀성을 확보하는 기술.

  • 비밀번호 암호화는 크게 2가지로 나뉜다.
    • 양방향
      • 복호화가 가능하다는 문제가 존재
    • 단방향(Hash)
      • 복호화 불가능

출처 https://blog.skby.net/암호화-encryption/

양방향

  • 대칭키
    • 암호화-복호화 키가 동일
    • 속도가 빠름
    • 키를 전달하는 과정에서 탈취 가능성 존재
    • 키를 통해 복호화 가능
  • 비대칭키(공개키)
    • 속도가 느림
    • 키가 공개되어 있어 탈취 가능성이 적음
    • 키를 통해 복호화 가능

단방향(Hash)

💡

해싱이란 입력값에 수학적 알고리즘(해시 함수)을 적용하여 고정된 크기의 문자열을 출력하는 과정

  • 속도가 빠름
  • 암호화 가능
  • 복호화 불가능

Hash - salt

Salt란 해싱되기 전에 추가적인 문자열을 더하여 해싱하는 방식

공격자가 무차별 대입을 통해 하나의 해시값(암호화된 비밀번호)에 대해 원 메시지를 찾았다면 공격자는 해당 해시 값을 가진 모든 사용자의 비밀번호를 알게 되는 것으로 이러한 상황을 막기위해 메시지에 Adding salt 작업을 하는 것

정리

  • 양방향 방식의 경우 키라는 존재가 탈취 또는 노출 시 복호화가 가능하는 치명적인 단점이 존재
  • 기본적으로 암호화가 가능하며, 복호화가 불가능한 단방향 방식을 사용해야 한다.

구현

@Component
public class CustomEncryptionComponent {

    public String encryptPassword(String email, String password) {
        try {
            KeySpec spec = new PBEKeySpec(password.toCharArray(), getSalt(email), 85319, 128);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

            byte[] hash = factory.generateSecret(spec).getEncoded();
            return Base64.getEncoder().encodeToString(hash);
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException
                 | InvalidKeySpecException e) {
            throw new RuntimeException(e);
        }
    }

    private byte[] getSalt(String email)
        throws UnsupportedEncodingException, NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-512");
        byte[] key = email.getBytes(StandardCharsets.UTF_8);

        return digest.digest(key);
    }
}
  • PBEKeySpec : 해당 클래슨는 비밀번호 기반 암호화(PBKDF2)에서 사용될 키의 스펙을 정의
  • SecretKeyFactory : 정의한 키 스펙을 통해 비밀 키를 생성 PBKDF2(공개키 표준 알고리즘) 알고리즘 기반으로 HMAC-SHA1 해시 함수를 기반으로 키를 생성할 수 있는 팩토리를 생성
  • getSalt() : 해당 서비스에서는 사용자 이메일에 대해 중복을 막고 있어 사용자 마다 모두 다른 이메일 값을 가질것으로 Salt 값에 적합하다 생각
  • MessageDigest.getInstance("SHA-512") : sha-256 보다는 동일한 문자열 입력 시 해시 값의 길이 긴 sha 512 가 더 안전하다 생각
💡

Digest란? 암호화 알고리즘을 통해 출련된 해시 값
ex) ,SHA-512 알고리즘을 사용하여 "Hello, World!"라는 문자열을 해시하면 생성된 512비트 길이의 해시 값

profile
정신차려 이 각박한 세상속에서!!!

0개의 댓글