Salt는 암호화된 비밀번호의 보안을 강화하기 위한 임의의 데이터를 의미합니다. 일반적으로 비밀번호를 해시화할 때 Salt를 추가하여, 동일한 비밀번호라도 매번 다른 해시 값을 생성하도록 만듭니다. 이를 통해 무차별 대입 공격(Brute Force Attack)과 레인보우 테이블 공격(Rainbow Table Attack) 같은 공격을 방어할 수 있습니다.
- 동일한 비밀번호에 대한 다른 해시 값 생성:
- 만약 사용자가 동일한 비밀번호를 사용하더라도, Salt를 추가하여 해시화하면 서로 다른 해시 값이 생성됩니다.
- 예를 들어,
password123
라는 비밀번호가 두 명의 사용자에게 입력되었을 때, 두 명의 사용자에게 저장되는 해시 값은 서로 달라집니다.
- 레인보우 테이블 공격 방어:
- 레인보우 테이블은 미리 계산된 해시 값과 원본 비밀번호를 매칭시킨 테이블입니다. 이를 통해 해시된 비밀번호를 빠르게 복호화할 수 있습니다.
- Salt를 사용하면 동일한 비밀번호라도 매번 다른 해시 값을 생성하기 때문에, 레인보우 테이블을 사용한 공격을 어렵게 만듭니다.
- 무차별 대입 공격 방어:
- 무차별 대입 공격은 가능한 모든 비밀번호 조합을 시도하는 방식입니다. Salt를 사용하면 해시 값이 다르므로 공격자가 매번 새로운 해시 값을 계산해야 하므로 공격 속도가 느려집니다.
Salt 과정
- Salt 생성:
- Salt는 일반적으로 랜덤한 문자열로 생성됩니다. 이 문자열은 비밀번호와 결합하여 해시화됩니다.
- Salt와 비밀번호 결합:
- 비밀번호와 Salt를 결합하여 새로운 문자열을 만들고, 이를 해시 함수에 전달하여 해시 값을 생성합니다.
- 예를 들어, 비밀번호
password123
와 SaltrandomSalt
를 결합하면password123randomSalt
라는 문자열이 만들어지고, 이 문자열이 해시화됩니다.
- Salt 저장:
- Salt는 해시 값과 함께 저장됩니다. 이때, Salt는 평문으로 저장되며, 해시 값과 함께 데이터베이스에 저장됩니다.
- 비밀번호를 검증할 때는, 저장된 Salt를 다시 사용하여 동일한 방법으로 해시화하고, 결과를 비교합니다.
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class SaltExample {
public static void main(String[] args) {
String password = "password123";
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
// 비밀번호 해시화 (자동으로 Salt를 생성하고 포함)
String encodedPassword = encoder.encode(password);
System.out.println("Encoded Password: " + encodedPassword);
// 비밀번호 검증
boolean matches = encoder.matches(password, encodedPassword);
System.out.println("Password matches: " + matches);
}
}
출력 예시:
Encoded Password: $2a$10$e8a5d9d4b8a9e6f78c9e5fcb0e2d1d5a2d5f19e4d47f35f4a5h5W
Password matches: true
단방향 해시 함수는 해시된 값만으로 원래 비밀번호를 추측하는 것이 매우 어렵도록 설계되어 있습니다. 이를 통해 비밀번호의 안전성을 높이고 비밀번호 유출 시에도 공격자가 원본 비밀번호를 쉽게 추측할 수 없도록 만듭니다. BCrypt
와 같은 알고리즘은 Salt, 반복적인 해시 계산, 단방향 해시 특성을 결합하여 비밀번호 보안을 강화합니다.
- Salt 생성 및 결합: Salt는 해시 계산에 사용되는 무작위 값으로, 같은 비밀번호라도 다른 Salt를 사용하면 다른 해시 값을 생성합니다. 이를 통해 동일한 비밀번호라도 서로 다른 해시 값을 만들어 해시 충돌 공격을 방지합니다.
- 비밀번호와 Salt 결합: 비밀번호와 Salt는 결합되어 단방향 해시 함수에 입력됩니다. 해시 함수는 이 입력을 통해 고정된 길이의 해시 값을 생성하는데, 이 과정에서 원본 데이터를 복원할 수 없습니다.
- 반복적인 해시 계산 (Work Factor): 해시 함수는 비용 인자(work factor)를 사용하여 해시 계산을 반복적으로 수행합니다. 이로 인해 해시 계산이 매우 느려지며, 무차별 대입 공격이나 사전 공격을 어렵게 만듭니다. 이 방식은 공격자가 해시 값을 추측하기 위해 많은 시간을 소모하도록 만듭니다.
- 복원 불가능성: 단방향 해시는 복원 불가능하다는 특성이 있습니다. 즉, 해시 값만으로 원본 데이터를 역으로 추적할 수 없습니다. 해시 함수는 입력값을 고정된 길이의 출력값으로 변환하는데, 이 과정에서 정보가 손실되므로 원본 데이터를 알 수 없습니다.
- Salt가 포함된 암호화된 비밀번호:
BCrypt
에서 생성된 암호화된 비밀번호에는 Salt가 포함되어 있습니다. 하지만 이 Salt만으로는 원본 비밀번호를 추측할 수 없습니다. 공격자는 Salt와 해시 값을 이용해 무차별 대입 공격을 시도할 수 있지만, 단방향 해시의 특성상 이를 성공시키는 데에는 엄청난 시간과 자원이 소모됩니다.
- 비밀번호 X 제공: 사용자가 비밀번호를 입력합니다.
- 무작위 Salt A 생성: 매번 다른 무작위 Salt를 생성합니다. 이 Salt는 비밀번호와 결합되어 해시 과정에 사용됩니다.
- Salt와 비밀번호 결합: Salt와 비밀번호를 결합하여 해시 함수에 넣습니다.
- 해시 값 생성: Salt와 비밀번호를 사용하여 반복적인 해시 계산을 수행하고, 최종적으로 암호화된 비밀번호 P를 생성합니다.
유출된 암호화된 비밀번호 (P)와 Salt (A) 사용
5. P 유출: P
는 암호화된 비밀번호이고, 이 안에는 이미 Salt A가 포함되어 있습니다.
6. 공격자의 접근: 공격자는 P
와 A
를 알게 되지만, 단방향 해시이기 때문에 P
와 A
만으로 원래의 비밀번호 X
를 역으로 추적하는 것은 불가능합니다.
대칭키(Symmetric Key)는 암호화와 복호화에 같은 키를 사용하는 방식입니다. 즉, 데이터를 암호화할 때 사용한 키와 데이터를 복호화할 때 사용하는 키가 같은 키입니다. 대칭키 암호화는 비교적 빠르고 효율적인 방식으로, 주로 대량의 데이터 암호화에 사용됩니다. 다만, 키를 안전하게 관리하고 공유하는 것이 중요한 단점이 있습니다.
장점:
- 속도: 대칭키 암호화는 빠르고 효율적입니다. 같은 키를 사용하여 암호화와 복호화를 하기 때문에 처리 속도가 빠릅니다.
- 간단성: 대칭키 방식은 구현이 간단하고, 많은 양의 데이터를 빠르게 암호화할 수 있습니다.
단점:
- 키 분배 문제: 대칭키 암호화의 주요 문제는 키를 안전하게 전달하는 것입니다. 만약 키가 탈취되면 보안에 큰 문제가 생길 수 있습니다.
- 키 관리의 어려움: 여러 사람이나 시스템이 대칭키를 사용하려면, 각 시스템 간에 키를 공유해야 하므로 키 관리가 복잡해질 수 있습니다.
대칭키 암호화는 주로 데이터 전송 및 저장에 많이 사용됩니다. 예를 들어:
- 파일 암호화: 민감한 파일을 암호화하여 저장할 때.
- 네트워크 통신: 안전한 통신을 위해 HTTPS에서 대칭키를 사용하여 데이터를 암호화합니다.
- 디스크 암호화: 하드 드라이브나 USB 장치의 데이터를 암호화하는 데 사용됩니다.
대칭키 암호화 방식에는 여러 가지 알고리즘이 있습니다. 그중에서 널리 사용되는 몇 가지는 다음과 같습니다:
- AES (Advanced Encryption Standard): 현재 가장 널리 사용되는 대칭키 암호화 알고리즘으로, 빠르고 안전합니다.
- DES (Data Encryption Standard): 과거에 많이 사용되었지만 현재는 보안상 취약점이 있어 잘 사용되지 않습니다.
- 3DES (Triple DES): DES의 보안 문제를 해결하려고 3번의 암호화를 적용한 알고리즘입니다.
비대칭키(Asymmetric Key) 암호화는 두 개의 키를 사용하는 방식으로, 하나는 공개 키(Public Key)이고 다른 하나는 비공개 키(Private Key)입니다. 이 방식은 데이터를 암호화하고 복호화하는 데 서로 다른 키를 사용합니다.
- 암호화: 데이터를 암호화할 때 공개 키를 사용합니다. 공개 키는 모든 사람이 사용할 수 있기 때문에 누구나 데이터를 암호화할 수 있습니다.
- 복호화: 암호화된 데이터를 복호화할 때는 비공개 키를 사용합니다. 비공개 키는 오직 키의 소유자만 알고 있기 때문에, 복호화는 오직 해당 키 소유자만 할 수 있습니다.
생성:
- 비공개키(Private Key)를 먼저 생성
- 비공개키는 완전 랜덤한 값으로 만들어짐.
- 이 키는 절대 외부에 노출되지 않음.
- 공개키(Public Key)는 비공개키를 기반으로 유도
- 비공개키에서 수학적 연산을 통해 공개키가 생성됨.
- RSA의 경우 모듈러 연산, ECC의 경우 타원 곡선 연산을 통해 공개키를 유도함.
- 공개키로부터 비공개키를 유도하는 것은 사실상 불가능.
장점:
- 키 분배의 용이함: 공개 키는 아무에게나 공개할 수 있기 때문에, 비공개 키를 안전하게 관리할 수 있다면 키 분배 문제가 해결됩니다. 대칭키 암호화는 키를 안전하게 전달하는 것이 어렵지만, 비대칭키는 이를 자연스럽게 해결합니다.
- 인증 및 서명: 비대칭키를 사용하면, 메시지를 암호화하거나 디지털 서명을 할 수 있기 때문에 인증 및 무결성을 제공할 수 있습니다. 예를 들어, 메시지를 비공개 키로 서명하면, 해당 서명이 공개 키로 확인되어 진위 여부를 검증할 수 있습니다.
단점:
- 속도: 비대칭키 암호화는 대칭키 암호화보다 훨씬 느립니다. 따라서 대량의 데이터를 암호화하는 데 비대칭키를 사용하기엔 비효율적입니다.
- 복잡성: 대칭키 암호화는 구현이 간단한 반면, 비대칭키 암호화는 상대적으로 구현이 복잡하고 연산이 많이 필요합니다. 비대칭키 암호화의 사용 사례 비대칭키 암호화는 보통 데이터의 안전한 전송과 인증에 사용됩니다. 예를 들어:
사용 사례:
- SSL/TLS: 웹사이트와 클라이언트 간의 안전한 통신을 위해 공개 키와 비공개 키를 사용합니다. 이를 통해 HTTPS가 안전하게 작동합니다.
- 디지털 서명: 비공개 키로 서명하고, 공개 키로 서명의 진위를 검증합니다. 이는 이메일, 소프트웨어 배포 등에서 많이 사용됩니다.
- 키 교환: 두 시스템이 안전하게 대칭키를 교환할 때 비대칭키를 사용하여 대칭키를 암호화하고 안전하게 전달합니다.
비대칭키 암호화는 보통 데이터의 안전한 전송과 인증에 사용됩니다. 예를 들어:
- SSL/TLS: 웹사이트와 클라이언트 간의 안전한 통신을 위해 공개 키와 비공개 키를 사용합니다. 이를 통해 HTTPS가 안전하게 작동합니다.
- 디지털 서명: 비공개 키로 서명하고, 공개 키로 서명의 진위를 검증합니다. 이는 이메일, 소프트웨어 배포 등에서 많이 사용됩니다.
- 키 교환: 두 시스템이 안전하게 대칭키를 교환할 때 비대칭키를 사용하여 대칭키를 암호화하고 안전하게 전달합니다.
비대칭키 암호화에서 사용하는 알고리즘은 여러 가지가 있으며, 대표적인 것들은 다음과 같습니다:
- RSA (Rivest–Shamir–Adleman): 가장 널리 사용되는 비대칭키 암호화 알고리즘입니다. 암호화 및 서명에 사용됩니다.
- ECC (Elliptic Curve Cryptography): RSA보다 더 작은 키 사이즈로 같은 수준의 보안을 제공할 수 있어, 효율적인 비대칭키 암호화 방식입니다.
- DSA (Digital Signature Algorithm): 디지털 서명을 위해 주로 사용되는 알고리즘입니다.
- 대칭키 암호화: 암호화와 복호화에 같은 키를 사용합니다. 속도는 빠르지만, 키를 안전하게 전달하는 문제가 발생합니다.
- 비대칭키 암호화: 암호화에 공개 키를 사용하고, 복호화에 비공개 키를 사용합니다. 이 방식은 키 분배 문제를 해결하지만, 속도나 효율성에서 대칭키 암호화보다는 느립니다.
비대칭키 암호화는 일반적으로 대칭키 암호화와 함께 사용됩니다. 비대칭키는 대칭키를 안전하게 교환하는 데 사용하고, 실제 데이터 암호화는 대칭키로 처리하여 속도 문제를 해결합니다. 이 방식은 SSL/TLS와 같은 시스템에서 사용됩니다.
A에서 B로 대칭키를 보내는 과정입니다.
1. B는 비대칭키(공개키, 비공개키)를 생성합니다.
2. B는 공개키와 함께 A에게 대칭키를 보내달라는 요청을 보냅니다.
3. A는 받은 공개키로 보유한 대칭키를 암호화하고 B에게 전송합니다.
4. B는 받은 암호화된 대칭키를 비공개키로 복호화합니다.
PEM (Privacy-Enhanced Mail) 형식은 주로 암호화된 데이터를 텍스트 형식으로 저장하고 전송하기 위해 설계된 형식입니다. PEM 형식은 데이터를 Base64로 인코딩한 후, 이를 헤더와 푸터로 감싸는 방식입니다.
- 헤더와 푸터:
-----BEGIN PUBLIC KEY-----
와-----END PUBLIC KEY-----
부분은 이 데이터가 공개키라는 것을 명시합니다.
- Base64로 인코딩된 데이터:
- 실제 키 데이터는 Base64로 인코딩된 이진 데이터입니다. Base64는 이진 데이터를 ASCII 문자로 변환하는 방식으로, 이진 데이터가 텍스트 형식으로 안전하게 전송될 수 있도록 합니다.
예를 들어, RSA 공개키를 PEM 형식으로 표현한 것은 다음과 같습니다:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Ue7kIcE3fXZkM7JZ8uX
vBdXhztkcHPCm7vnEjO+xUKXtkfnyo31z5oCkeqQlrNmw0azB79qkgHqs6YP9O4z
8GcACXcHpcT1+O3y+mgmFQt2AgtOTqIxlEwHzg3OAyH6pVEjOtsZsmUnH+DQvZG9
qWmTP5ZD3RHV58kZGJjyXYyIbwzLHF9DboyQmAX5Vq9hsdqb5UqkqwmipfZmcU4s
3mYnbMNp/J6faYeie5q59t1m4kQ8j4z3slYVr4JY0g/qw3RYo5lszzh4RzgT05dG
s0L9b7zxwVr+Ikm8XrJ7dO5KP4pqfkmxhbVuLdoVoMi6DgA1IcU7Jl2VFT1E0xu2
hwIDAQAB
-----END PUBLIC KEY-----