회원가입을 API를 만들때 비밀번호는 암화화 해줘야한다 권장사항이 아니라 강제 사항이다 아래는 개정된 개인정보 법이다.

비밀번호를 평문으로 저장하면 데이터 유출 시 모든 사용자의 비밀번호가 그대로 노출되어 2차 피해가 발생할 수 있고 내부 직원이 DB를 조회해 사용자 비밀번호를 볼 수 있어 악용될 위험이 있다
일단 암호화에 대해서 알아야하는데 암호화는 크게 양방향, 단방향 알고리즘으로 나뉜다 단반향과 양방향에 대해서 알아보자

대칭키 암호화는 데이터를 암호화하여 민감한 정보를 숨길 수 있지만, 키가 유출되면 평문으로 복호화할 수 있어 보안에 취약하다. 비대칭키 암호화도 양방향 암호화 방식이지만, 개인키가 유출되면 암호화된 데이터를 복호화할 수 있어 보안 문제가 발생할 수 있다.
✅ 장점
❌ 단점
MD5 (Message Digest Algorithm 5)
SHA-1 (Secure Hash Algorithm 1)
SHA-2 (Secure Hash Algorithm 2)
비밀번호를 안전하게 보호하려면 어떤 해시 함수를 선택해야 하는지 고민해야 한다. 앞서 살펴본 것처럼, 일부 해시 알고리즘은 보안이 취약하여 현재는 사용이 권장되지 않는다.
하지만 SHA-2조차 비밀번호 해싱용으로는 적절하지 않을 수 있다. 왜냐하면, SHA 계열 알고리즘은 설계상 빠른 연산 속도를 목표로 하기 때문이다. 해싱 속도가 빠르면 공격자 역시 더 빠르게 대량의 비밀번호를 해독할 수 있어 보안성이 떨어질 수 있다. 그렇다면 어떻게 비밀번호가 탈취될까??
레인보우 테이블은 모든 문자열의 해시 값을 저장하는 것이 아니라, 특정 문자와 숫자의 조합에 제한을 두고 저장하는 방식이다.
또한, 레인보우 테이블의 크기를 줄이기 위해 해시 값을 다시 변환하여 저장하는 함수(Reduction Function)를 사용할 수도 있다. 이를 통해 저장 공간을 절약하면서도 해킹 공격을 효율적으로 수행할 수 있다.
공격자는 레인보우 테이블을 이용해 서버에 저장된 해시 값과 대조하여 원래 비밀번호를 추론할 수 있다.
이런 레인보우 테이블 공격을 막기위해 나온게 Salt이다
위의 문제를 보안하기 위해 단방향 암호화를 진행할 때 솔팅(Salting)과 키 스트레칭(Key Stretching)을 적용 시킨다.
Salting
솔팅은 단방향 해시 함수 암호화를 진행 할 때 본래 데이터에 추가적으로 랜덤한 데이터를 더하는 방식이다. 원래 데이터에 추가 데이터가 포함 되었기 때문에 이전의 해시값과 달라진다.
Salt

레인보우 테이블 공격의 경우 특정 문자에 대한 출력해시를 입력해서 원본을 찾아내는 방식인데, Salt가 추가되면 공격자가 알게되는 원본은 '비밀번호'가 아닌 '비밀번호 + Salt'이다.
키 스트레칭(Key Stretching)
단방향 해쉬값을 계산 한 후, 그 해쉬값을 또 다시 해시하고 또 이를 반복하는 방식이다. 최근 일반적인 장비로도 1초에 50억 개 이상의 해시값을 비교할 수 있다. 하지만 키 스트레칭을 적용하면 동일 장비에서 1초에 5번 정도만 비교할 수 있다. GPU(Graphics Processing Unit)를 사용하더라도 수백에서 수천 번 정도만 비교할 수 있다.
Bcrypt 알고리즘은 비밀번호 저장을 위해 설계된 해시 함수로, 해시 값을 생성하는 데 시간이 오래 걸리는 구조를 가진다.
솔팅과 키 스트레칭을 결합한 계산 방식을 사용하며, 이러한 방식을 Adaptive Key Derivation Function이라 부른다.
이 방식은 GPU 병렬 연산을 어렵게 만들어 브루트포스 공격과 레인보우 테이블 공격을 어렵게 만든다.
이렇게 정리한 이유는 Bcrypt를 사용하기 위해서다.
예전에는 단순히 암호화를 위해 쓰는 기술이라고만 생각했지만, 이번 프로젝트를 통해 "왜 Bcrypt를 써야 할까?" 라는 의문을 가지게 됐다.

위의 코드는 Spring Security 설정 클래스이며,
@Bean을 사용해 BcryptPasswordEncoder를 등록하여 비밀번호 암호화를 적용하고 있다
이렇게 하면 Spring 컨테이너에서 PasswordEncoder 빈을 관리하게 되어,
서비스나 리포지토리에서 비밀번호 암호화 및 검증 시 주입받아 사용할 수 있다.
String aPassword = passwordEncoder.encode(createMemberDTO.getPassword());
결과값

https://deediims.tistory.com/32
https://study-easy-coding.tistory.com/153
https://blog.skby.net/%EC%95%94%ED%98%B8%ED%99%94-encryption/