사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 하는 공격을 말한다.
ex) 똑같은 모습으로만든 피싱사이트로 개인정보 빼내는행위
방어방법
Referrer 검증
Back-end 단에서 request의 referrer를 확인하여 domain (ex. naver.com) 이 일치하는 지 검증하는 방법입니다
Security Token 사용 (A.K.A CSRF Token)
Security Token를 활용할 수 있습니다. 우선 사용자의 세션에 임의의 난수 값을 저장하고 사용자의 요청 마다 해당 난수 값을 포함 시켜 전송시킵니다. 이후 Back-end 단에서 요청을 받을 때마다 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는 지 검증하는 방법입니다.
Spring Security에서는 비밀번호를 안전하게 저장할 수 있도록 비밀번호의 단방향 암호화를 지원하는 PasswordEncoder 인터페이스와 구현체들을 제공합니다. 이 인터페이스는 아래와 같이 심플하게 구성되어 있습니다.
public interface PasswordEncoder {
// 비밀번호를 단방향 암호화
String encode(CharSequence rawPassword);
// 암호화되지 않은 비밀번호(raw-)와 암호화된 비밀번호(encoded-)가 일치하는지 비교
boolean matches(CharSequence rawPassword, String encodedPassword);
// 암호화된 비밀번호를 다시 암호화하고자 할 경우 true를 return하게 설정
default boolean upgradeEncoding(String encodedPassword) { return false; };
}
BcryptPasswordEncoder : BCrypt
해시 함수를 사용해 비밀번호를 암호화
Argon2PasswordEncoder : Argon2
해시 함수를 사용해 비밀번호를 암호화
Pbkdf2PasswordEncoder : PBKDF2
해시 함수를 사용해 비밀번호를 암호화
SCryptPasswordEncoder : SCrypt
해시 함수를 사용해 비밀번호를 암호화
위 4개의 PasswordEncoder는 Password를 encode할 때, 매번 임의의 salt를 생성해서 encode 하게 되어 있습니다.
SHA
암호학적 해시 알고리즘의 모음
하지만 SHA2, SHA3 는 너무 빠른게 오히려 단점이다.
Bcrypt
애초부터 패스워드 저장을 목적으로 설계되었다.
Bcrypt는 조정할 수 있는 해시알고리즘을 써서 패스워드를 저장한다.
반복횟수를 변수로 지정가능하게 하여 작업량 (=해싱시간) 을 조절할 수 있게 해주었다.
→ 원하는 만큼 속도를 조절가능한 hash 함수.
Bcrypt는 패스워드를 해싱할 때 내부적으로 랜덤한 솔트를 생성하기 때문에 같은 문자열에 대해서 다른 인코드된 결과를 반환한다. 하지만 공통된 점은 매번 길이가 60인 String을 만든다.
SCrypt
scrypt는 다이제스트를 생성할 때 메모리 오버헤드를 갖도록 설계되어, 억지 기법 공격(brute-force attack)을 시도할 때 병렬화 처리가 매우 어렵다. 따라서 PBKDF2보다 안전하다고 평가되며 미래에 bcrypt에 비해 더 경쟁력이 있다고 여겨진다.
Argon2
키 유도 함수(key derivation function) 의 일종으로 2015년 Password Hashing Competition 에서 우승한 사용자의 암호를 해싱하는데 유용한 알고리즘입니다.
argon2 는 암호를 해싱하는데 걸리는 시간이나 소요되는 메모리 양을 설정할 수 있게 설계되었으므로 사용하는 목적에 맞게 파라미터 변경으로 적용이 가능합니다
실행 시간을 정의 하는 시간 비용
메모리 사용량을 정의 하는 메모리 비용
스레드 수를 정의 하는 병렬 도
Pbkdf2
PBKDF2는 솔트를 적용한 후 해시 함수의 반복 횟수를 임의로 선택할 수 있다. PBKDF2는 아주 가볍고 구현하기 쉬우며, SHA와 같이 검증된 해시 함수만을 사용한다.
PBKDF2의 기본 파라미터는 다음과 같은 5개 파라미터다.
PRF: 난수(예: HMAC)
Password: 패스워드
Salt: 암호학 솔트 (32bit 이상 추천)
c: 원하는 iteration 반복 수 (1000번 이상 추천 )
DLen: 원하는 다이제스트 길이
Rainbow Table
해시 함수를 사용하여 변환 가능한 모든 해시 값을 저장시켜 놓은 표이다. 보통 해시 함수를 이용하여 저장된 비밀번호로부터 원래의 비밀번호를 추출해 내는데 사용된다.
Salt
솔트(salt)는 단방향 해시 함수에서 다이제스트를 생성할 때 추가되는 바이트 단위의 임의의 문자열이다. 그리고 이 원본 메시지에 문자열을 추가하여 다이제스를 생성하는 것을 솔팅(salting)이라 한다.
예를 들어 다음과 같이 "redfl0wer"에 솔트인 "8zff4fgflgfd93fgdl4fgdgf4mlf45p1"를 추가해 다이제스트를 생성할 수 있다.
key stretching
입력한 패스워드의 다이제스트를 생성하고, 생성된 다이제스트를 입력 값으로 하여 다이제스트를 생성하고, 또 이를 반복하는 방법으로 다이제스트를 생성할 수도 있다. 이렇게 하면 입력한 패스워드를 동일한 횟수만큼 해시해야만 입력한 패스워드의 일치 여부를 확인할 수 있다. 이것이 기본적인 키 스트레칭 과정이다.
잘 설계된 패스워드 저장 시스템에서는 하나의 다이제스트를 생성할 때 어느 정도(일반적인 장비에서 0.2초 이상)의 시간이 소요되게 설정한다. 이는 억지 기법 공격(brute-force attack)으로 패스워드를 추측하는 데 많은 시간이 소요되도록 하기 위한 것이다.
JAVA , JAVA + SPRING , JAVA + 하이버네이트 등 여러 프레임 워크에서 암복호화를 지원해주는 오픈소스이며
단방향(uni - directional) , 양방향(bi - directional) 암호화를 모두 지원해준다. 기타 기본적인 String , Number , Big Decimal
타입의 변수에 대하여 암호화를 지원해준다.