Bcrypt를 알아보기에 앞서 암호화, 복호화, 단방향, 양방향에 대해서 알아보자
암호화, 복호화, 단방향, 양방향
암호화
복호화
단방향
양방향
단반향 알고리즘으로 해시 알고리즘이 잘 알려져 있음
해시 알고리즘은 암호화 가능하지만, 복호화가 불가능하다는 점을 이용하여 데이터 무결성을 검증하기 위함
-> 데이터 무결성 : 데이터가 허락된 사용자로 인해 수정이 제대로 이루어졌는지, 허가되지 않은 사용자가 무단으로 데이터를 조작했는지 여부를 보는 것
암호문을 복호화할 수 있도록 구현된 암호 알고리즘
키의 성질에 따라 구분되는데, 대칭키 암호 알고리즘 과 비대치킹 암호 알고리즘이 있다
Bcrypt이용해서 패스워드 암호화하기
여기서 잠깐 SHA, Bcrypt중 Bcrypt를 이용하는 이유는..?
SHA 경우
- GPU를 이용한 연산속도가 매우 빠르기 때문에 password 암호화에 권장되지 않음
- GPU 연산속도가 빠를수록 공격자의 하드웨어를 통한 오프라인 brute force에 더 취약하다.
-> 빠른 해시를 사용하여 암호화를 진행시 공격자는 오프라인 공격으로 초당 수십억개의 해시를 계산할 수 있다.
Bcrypt경우
- 반복횟수를 늘려 연산속도를 늦출 수 있으므로 연산 능력이 증가하더라도 brute-forece 공격에 대비할 수 있음
salt ??
- 주로 비밀번호 해싱에서 랜덤한 데이터를 의미
- 원본 비밀번호에 추가되어, 해시함수의 입력으로 같이 제공
- 같은 비밀번호를 가진 사용자라도 다른 해시값을 생성하게 만들어 주는 것이 목적
솔트 사용 방법
- 사용자가 비밀번호 생성/변경시 랜던함 솔트 생성해서 원본 비밀번호에 추가
hash와 salt의 사용으로 똑같은 문자열 패스워드라도 다른 hash값 나옴
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
@Override
public boolean register(MemberInput parameter) {
Optional<Member> optionalMember = memberRepository.findById(parameter.getUserId());
if (optionalMember.isPresent()) {
//현재 userId에 해당하는 데이터 존재
return false;
}
String encPassword = BCrypt.hashpw(parameter.getPassword(), BCrypt.gensalt());
String uuid = UUID.randomUUID().toString();
Member member = Member.builder()
.userId(parameter.getUserId())
.userName(parameter.getUserName())
.phone(parameter.getPhone())
.password(encPassword)
.regDt(LocalDateTime.now())
.emailAuthYn(false)
.emailAuthKey(uuid)
.userStatus(Member.MEMBER_STATUS_REQ)
.build();
memberRepository.save(member);
return true;
}
public class PasswordUtils {
//비밀번호 맞는지 확인
public static boolean equals(String plaintext, String hashed) {
if (plaintext == null || plaintext.length() < 1) {
return false;
}
if (hashed == null || hashed.length() < 1) {
return false;
}
//사용자가 입력한 비미번호, DB에 저장되어있는 해시값
return BCrypt.checkpw(plaintext, hashed);
}
///비밀번호 암호화
public static String encPassword(String plaintext) {
if (plaintext == null || plaintext.length() < 1) {
return "";
}
return BCrypt.hashpw(plaintext, BCrypt.gensalt());
}
}