프로세스에서는 인증을 진행한 후에야 권한 부여가 진행된다는 점에서 인증과 권한 부여 사이의 시간적 선후관계는 존재한다고 볼 수 있다.
하지만, 인증과 권한 부여는 별개의 목적을 지닌 전혀 다른 프로세스이다.
극단적인 예로, 인증 없이도 권한 부여 프로세스를 진행할 수도 있고, 권한 부여 없이 인증만 진행할 수도 있다.
결과적으로 인증 프로세스를 사용자 측에서 본다면, '로그인' 부분을 뜻한다고 이해해도 무방
보안을 강화하려면, 최소한 2개 이상의 authentication factor를 사용하는 것이 좋다.
이는 사용자의 정보가 단 한 가지 요소에 의존하지 않게 하여 보안성을 강화한다.
1. SFA (Single Factor Authentication)은 한 개의 인증 요소를 사용하여 사용자의 신원을 확인하는 방법이다.
예를 들어, 사용자 이름과 비밀번호를 입력하는 것이 SFA 인증의 예.
2. 2FA (Two-Factor Authentication)은 두 개의 인증 요소를 사용하여 사용자의 신원을 확인하는 방법이다.
예를 들어, 사용자 이름과 비밀번호, 또는 비밀번호와 개인 고유 인증 기기 (예: 스마트폰)를 사용하는 것이 2FA 인증의 예.
3. MFA(Multi Factor Authentication)은 두 가지 이상의 확인 요소를 제공해야 하는 인증 방법이다.
"권한의 차등적 부여 관련 정보"와 관련해서 각종 Authorization 관련 기술들에 존재하는데,
대표적으로 Session에 특정 값을 넣어두고서 이를 체크하는 간단한 방식부터, JWT(JSON Web Token)이나 SAML(Security Assurance Markup Language), OAuth와 같은 기술들이 그것이다.
Salt
비밀번호 암호화에서 사용되는 추가 정보이다.
Salt 값은 비밀번호 해시(hash) 값과 함께 저장되어, 비밀번호가 암호화될 때마다 랜덤하게 생성된다.
따라서 같은 비밀번호에 대해서도 각각 다른 해시 값을 생성할 수 있다.
Salt 값은 암호화된 비밀번호를 복호화하는 것을 막아줌으로써 비밀번호의 보안을 강화하는 효과가 있다.해시(hash)
원래의 데이터를 암호화하여 다른 형태의 데이터로 변환하는 과정을 말한다.
패스워드의 경우, 사용자가 입력한 패스워드를 해시 함수를 통해 해시 값으로 변환하여 데이터베이스에 저장한다.
이 과정에서 사용되는 salt 값은 각 패스워드마다 고유한 값으로써, 보안에 추가적인 레이어를 제공한다.해시함수
- 해시함수는 임의의 길이의 데이터를 고정된 길이의 데이터로 출력하는 함수이다. 해시함수에 의해 얻어지는 값은 해시 값, 해시 코드, 해시 체크섬 또는 간단하게 해시라고 한다.
- 특성
- 일방향 함수(one-way function)로 다양한 길이의 입력을 고정된 짧은 길이의 출력으로 변환하는 함 수로 데이타의 무결성 검증, 메세지 인증에 사용한다
- 다양한 가변 길이의 입력에 적용될 수 있어야 한다.
- 고정된 길이의 출력을 만든다.
- 주어진 입력값을 해시하는 것은 쉽다.
- 해시 결과값으로 입력값을 계산하는 것은 불가능 하다.
- 동일한 해시값을 가지는 서로 다른 메시지 쌍이 없다.
Express 어플리케이션에서 비밀번호 암호화에 사용되는 해시 알고리즘
해시 알고리즘(Hash Algorithm)
데이터를 입력받아 고정된 길이의 고정된 값으로 변환하는 알고리즘
일반적으로 해시 알고리즘은 무엇이 입력되었던 상관없이 고정된 길이의 값으로 변환된다.
해시 알고리즘은 암호화, 무결성 검증, 중복 검사 등 다양한 목적으로 사용된다.
Bcrypt는 Blowfish 암호화 알고리즘을 기반으로 하며, 비밀번호의 암호화 결과값을 생성할 때 각종 파라미터를 설정할 수 있다.
Blowfish 암호화 알고리즘
1993년 Bruce Schneier에 의해 개발된 블록 암호화 알고리즘
Blowfish는 빠른 암호화 속도와 높은 보안성을 제공하는 특징이 있다.
이 알고리즘은 대용량 데이터에 대한 암호화에 적합하며, 암호화 결과값의 길이를 쉽게 조절할 수 있어 특정 용도에 맞게 사용할 수 있다.
Bcrypt가 기반이 된 Blowfish 암호화 알고리즘은 비밀번호의 암호화에 주로 사용된다.
Bcrypt는 암호화 결과값이 충분히 긴 길이를 갖으며, 매우 높은 암호화 알고리즘의 보안성을 가지고 있어 많은 애플리케이션에서 사용되고 있다.
또한 Bcrypt는 암호화 속도를 제한할 수 있는 기능을 갖추고 있어, 대용량의 요청에도 높은 안정성을 유지할 수 있다.
> npm i bcrypt
bcrypt.hash(password, saltRounds, callback)
함수를 사용하여 비밀번호 해시를 생성합니다.bcrypt.compare(password, hash, callback)
함수를 사용하여 입력한 비밀번호와 저장된 해시 값을 비교합니다.var bcrypt = require("bcrypt");
var password = "password123";
// bcrypt.hash 함수는 암호화된 비밀번호 해시 값을 생성하는데 사용
// password: 암호화할 비밀번호
// saltRounds: salt 값으로 사용될 랜덤 문자열의 길이. 길이가 길수록 공격자가 해시 값을 복원하는 것이 어렵다.
// callback: 해시 생성이 완료되면 실행될 콜백 함수. 첫 번째 매개변수로 오류 객체, 두 번째 매개변수로 암호화된 해시 값이 전달된다.
bcrypt.hash(password, 10, function (err, hash) {
if (err) {
console.error(err);
return;
}
console.log("Password hash:", hash);
// bcrypt.compare 함수는 입력된 비밀번호와 암호화된 해시 값이 일치하는지 확인하는데 사용
// password: 비교할 비밀번호
// hash: 암호화된 해시 값
// callback: 함수에서는 비교 결과를 받아와 처리할 수 있다. 비교 결과가 true이면 "password"와 "hash"가 일치한 것으로 판단되며, false이면 일치하지 않음을 의미.
bcrypt.compare(password, hash, function (err, result) {
if (err) {
console.error(err);
return;
}
console.log("Password match:", result);
});
});
var bcrypt = require("bcrypt");
var express = require("express");
var app = express();
app.post("/signup", function(req, res) {
var password = req.body.password;
bcrypt.hash(password, 10, function(err, hash) {
if (err) {
console.error(err);
res.status(500).send("Error while hashing the password");
return;
}
// Store the hash in the database
});
});
app.post("/login", function(req, res) {
var password = req.body.password;
var hashFromDb = ... // Retrieve the hash from the database
bcrypt.compare(password, hashFromDb, function(err, result) {
if (err) {
console.error(err);
res.status(500).send("Error while comparing the password");
return;
}
if (result) {
// The password is correct, grant access
} else {
// The password is incorrect, deny access
}
});
});
/signup
/login
엔드포인트(Endpoint)
는 클라이언트가 서버에 요청을 할 수 있는 주소(URL)을 말한다.
서버에서는 각각의 엔드포인트에 대해 미리 정의한 로직에 따라 요청을 처리한다.
예를 들어, 웹 어플리케이션에서는 /login과 같은 엔드포인트를 통해 로그인 기능을 제공할 수 있다.
bcrypt.hash(plainTextPassword, saltRounds, callback)
: 이 메서드는 주어진 plainTextPassword를 saltRounds 만큼 salt 값을 추가하여 해시값으로 변환합니다. 이 과정이 완료되면 callback 함수가 호출되며, 첫 번째 인수로 오류(err) 또는 두 번째 인수로 해시된 패스워드가 전달됩니다.
bcrypt.compare(plainTextPassword, hashedPassword, callback)
: 이 메서드는 주어진 plainTextPassword와 hashedPassword 값을 비교하여 같은 경우 true, 다른 경우 false를 반환합니다. callback 함수는 첫 번째 인수로 오류(err), 두 번째 인수로 결과 값(result)이 전달됩니다.
bcrypt.genSalt(saltRounds, callback)
: 이 메서드는 saltRounds 만큼 salt 값을 생성합니다. 생성된 salt 값은 callback 함수에서 첫 번째 인수로 전달됩니다.
bcrypt.genSalt(10, function (err, salt) {
if (err) {
console.error(err);
return;
}
bcrypt.hash("password", salt, function (err, hash) {
if (err) {
console.error(err);
return;
}
console.log(hash);
});
});
bcrypt.genSalt(10, callback)
을 호출하여 saltRounds에 10을, callback 함수를 전달한다.bcrypt.genSalt()
메서드는 saltRounds의 값에 따라 랜덤한 salt 값을 생성한다.bcrypt.hash()
메서드를 호출하여 비밀번호 "password"를 해싱한다.bcrypt.hash()
메서드가 완료되면, callback 함수에서 출력된 해싱된 값을 볼 수 있다.암호화 알고리즘은 원래의 데이터를 암호화된 형식으로 변환하는 수학적 연산을 사용한다.
복호화 키는 암호화된 데이터를 원래의 형식으로 변환하는 과정을 역전하는 데 사용된다.
이를 통해 민감한 정보는 도용 또는 무단 액세스로부터 보호되어 안정적으로 저장하고 전송할 수 있다.
복호화
복호화는 암호화된 데이터를 원래의 형태로 복원하는 것을 의미.
암호화는 보안상의 이유로 데이터를 암호화하여 전송 또는 저장하는 것이다.
그러나, 암호화된 데이터는 적절한 방법이 없으면 읽을 수 없다.
이러한 경우에, 복호화를 통해 암호화된 데이터를 원래의 형태로 복원할 수 있다.