암호화와 보안
1. 왜 암호화가 중요한가?
오늘날의 디지털 세상에서 데이터는 언제나 해킹 위험에 노출되어 있습니다. 특히, 사용자의 비밀번호와 같은 민감한 데이터가 데이터베이스에 평문으로 저장된다면, 해킹 시 치명적인 정보 유출이 발생할 수 있습니다. 이를 방지하기 위해 **암호화(Encryption)**와 **해시(Hashing)**가 사용됩니다.
2. 해시(Hashing)란 무엇인가?
**해싱(Hashing)**은 데이터의 무결성을 확인하거나 비밀번호를 안전하게 저장하는 데 사용됩니다.
해싱의 특징
- 단방향: 해시 함수는 원본 데이터를 복원할 수 없습니다.
- 고정된 출력값: 입력 데이터 크기에 관계없이 고정된 크기의 해시 값을 생성합니다.
- 충돌 가능성: 서로 다른 데이터가 동일한 해시 값을 생성할 수도 있습니다(충돌).
- 민감도: 입력 데이터가 조금이라도 바뀌면 해시 값이 완전히 달라집니다.
해시 함수의 사용 예시
- 비밀번호 저장: 데이터베이스에 비밀번호를 저장할 때, 원본 대신 해시 값을 저장합니다. 이렇게 하면 데이터베이스가 해킹되더라도 해시 값을 복원해 원본 비밀번호를 알 수 없습니다.
- 데이터 무결성 검증: 파일이 손상되거나 변경되지 않았는지 확인할 때 사용됩니다.
해시 알고리즘의 종류
- MD5: 빠르지만 보안 취약점으로 인해 잘 사용되지 않음
- SHA-1: 더 나은 보안성을 제공하지만, 충돌 문제가 있어 사용이 줄어듦
- SHA-256: 현재 가장 널리 사용되며 높은 보안성을 제공
3. 비밀번호 저장과 해싱의 실제 사례
비밀번호 저장 시, 단순 해싱은 보안상 위험할 수 있습니다. 이를 보완하기 위해 **솔트(Salt)**와 반복 해싱을 사용합니다.
- 솔트(Salt): 고유한 임의 값을 비밀번호에 추가해 동일한 비밀번호라도 서로 다른 해시 값을 생성하도록 합니다.
- 반복 해싱: 해시 함수를 반복 적용해 해시 충돌 가능성을 줄이고, 무차별 대입 공격(Brute Force Attack)을 방어합니다.
Node.js 예제
const bcrypt = require("bcrypt");
// 비밀번호 해싱
const saltRounds = 10;
const plainPassword = "mypassword";
bcrypt.hash(plainPassword, saltRounds, (err, hash) => {
console.log("Hashed Password:", hash);
});
// 비밀번호 검증
bcrypt.compare("mypassword", hash, (err, result) => {
console.log("Password Match:", result); // true or false
});
JWT(Json Web Token): 인증의 새로운 표준
1. JWT란?
**JWT(Json Web Token)**는 사용자 인증과 정보 전달을 위해 사용되는 JSON 기반의 토큰입니다. 서버가 클라이언트에 인증 정보를 안전하게 전달하고, 클라이언트는 이 정보를 바탕으로 서버와 상호작용할 수 있습니다.
2. JWT의 구조
JWT는 점을 기준으로 3개의 부분으로 나뉜다. ex) dfjdk321fe.w1wdct.fb4bd
Header: 토큰의 타입(JWT)과 해싱 알고리즘 정보를 포함
{
"alg": "HS256",
"typ": "JWT"
}
Payload: 사용자 정보와 같은 데이터가 포함됩니다.
{
"userId": 123,
"username": "john_doe",
"exp": 1672531200
}
Signature: Header와 Payload를 비밀 키로 서명한 값.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywidXNlcm5hbWUiOiJqb2huX2RvZSIsImV4cCI6MTY3MjUzMTIwMH0.jVL1nXZlQzU1hRh5ktF6kRZm1l6GvP6m5L3-w0Sh4Fg
3. JWT의 사용 흐름
- 로그인 요청: 사용자가 ID/비밀번호를 입력해 서버에 로그인 요청.
- 토큰 발급: 서버는 사용자 인증 후 JWT를 발급해 클라이언트에 전달.
- 토큰 저장: 클라이언트는 JWT를 브라우저의 쿠키나 로컬 스토리지에 저장.
- 인증 요청: 클라이언트가 서버로 요청을 보낼 때 JWT를 포함.
- 토큰 검증: 서버는 JWT의 서명과 유효기간을 검증해 요청을 처리
4. JWT와 암호화의 관계
- JWT 자체는 암호화된 데이터가 아닙니다.
- 대신, 토큰의 무결성을 확인하기 위해 **서명(Signature)**을 사용합니다.
- 민감한 정보를 포함해야 할 경우, 별도의 **암호화(Encryption)**를 적용해야 합니다.
5. JWT 예제
Node.js로 JWT 생성 및 검증
const jwt = require("jsonwebtoken");
const secretKey = "mysecretkey";
// JWT 생성
const token = jwt.sign({ userId: 123, username: "john_doe" }, secretKey, {
expiresIn: "1h"
});
console.log("Generated Token:", token);
// JWT 검증
try {
const decoded = jwt.verify(token, secretKey);
console.log("Decoded Token:", decoded);
} catch (err) {
console.error("Token Verification Failed:", err.message);
}
해싱은 비밀번호와 데이터 무결성을 보호하는 데 사용되며, 데이터베이스 보안을 강화합니다. JWT는 인증 시스템에서 세션 관리 없이 사용자 정보를 안전하게 전달할 수 있는 강력한 도구입니다. 이 두 가지는 독립적으로 사용되지만, 함께 사용하면 더욱 안전하고 유연한 인증 시스템을 구축할 수 있습니다.
JWT는 암호화된 데이터가 아니라 서명된 데이터로 Payload에 저장된 데이터는 누구나 읽을 수 있으므로 비밀번호나 민감한 정보는 JWT에 절대 저장하지 않습니다.
Salt
1. Salt란?
- Salt는 비밀번호를 해싱(Hashing)할 때 보안을 강화하기 위해 사용되는 고유한 랜덤 값입니다.
- 동일한 비밀번호라도 Salt 값이 다르면 서로 다른 해시 결과를 생성합니다.
2. Salt의 특징
- 비밀번호 해싱에 사용:
- 비밀번호를 해싱하기 전에 Salt를 추가하여 Rainbow Table Attack(무작위 대입 공격)을 방지합니다.
- DB에 저장:
- Salt 값은 비밀번호 해시와 함께 데이터베이스에 저장됩니다.
- 서버가 비밀번호를 검증할 때 사용됩니다.
- 단방향 암호화:
- Salt를 사용한 해싱은 단방향 암호화이므로 복호화가 불가능합니다.
3. Salt 사용 흐름
- 사용자가 회원가입 시 비밀번호를 입력.
- 서버는 랜덤하게 생성된 Salt를 비밀번호에 추가하여 해싱.
- 해싱된 비밀번호와 Salt 값을 데이터베이스에 저장.
- 사용자가 로그인 시 비밀번호를 입력하면, 저장된 Salt 값을 사용해 다시 해싱 후 비교.
Salt 예제
const bcrypt = require('bcrypt');
// 비밀번호 해싱
const saltRounds = 10;
const password = "mypassword";
const hashedPassword = bcrypt.hashSync(password, saltRounds);
console.log("Hashed Password:", hashedPassword);
// 비밀번호 검증
const isMatch = bcrypt.compareSync("mypassword", hashedPassword);
console.log("Password Match:", isMatch); // true
JWT와 Salt의 차이
특징 | JWT | Salt |
주된 목적 | 인증 정보 저장 및 전송 | 비밀번호 보안 강화 |
구성 요소 | Header, Payload, Signature | 고유한 랜덤 문자열 |
사용 목적 | 클라이언트-서버 간 인증 정보를 전달 | 비밀번호 해싱에 추가 |
저장 위치 | 클라이언트(쿠키 또는 로컬 스토리지) | 서버(DB에서 해시와 함께 저장) |
보안 방식 | 토큰 서명을 통해 무결성 확인 | 해시 결과를 고유화 |
복호화 가능 여부 | 복호화 불가능(하지만 Payload는 누구나 읽을 수 있음) | 복호화 불가능 |
사용 사례 | 인증 및 권한 관리 | 비밀번호 저장 |
- Salt: 비밀번호를 안전하게 저장하기 위해 사용하며, 비밀번호를 해싱할 때 추가되는 값.
- JWT: 인증과 권한 관리를 위해 사용되며, 클라이언트와 서버 간 상태를 유지하지 않는 인증 방식.
- Salt는 서버에서 저장되고 검증 과정에서만 사용되며, JWT는 클라이언트에 저장되어 서버와의 요청에 사용됩니다.
'Web' 카테고리의 다른 글
JavaScript 자료 구조와 메모리 관리 (3) | 2024.11.15 |
---|---|
CSS - Flex Box로 레이아웃 디자인하기 (0) | 2024.11.04 |
웹 표준과 웹 접근성이란? (8) | 2024.10.29 |