Hash는 복호화가 되지않는 일방향 함수라는 특징을 가지고있다.
그래서 한번 Hash함수를 적용하면 되돌릴수가없다. (암호화, 인코딩은 복호화,디코딩을 통해 되돌릴수 있음)
데이터베이스에 패스워드를 Hash암호화 해서 Insert를 한 후
로그인시에는 Hash한 패스워드값을 비교하여 로그인기능이 정상적으로 작동하도록 만들어보았다.
회원가입 함수에
$hashpwd = hash("md5", $userPwd); // md5($userPwd) 로도 사용가능 & hash("algo","data")
를 추가해주었다.
로그인시에는 해쉬함수를 적용한 값을 비교하여 일치하면 로그인되도록 변경해주었다.
function login4($userId,$userPwd){ //Hash 식별인증분리
define('DB_SERVER','localhost');
define('DB_USERNAME','admin');
define('DB_PASSWORD','student1234');
define('DB_NAME','test');
$db_conn = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_NAME);
$hashpwd = hash("md5",$userPwd);
$sql = "select * from test_table where name='".$userId."'";
$result = mysqli_query($db_conn,$sql);
$row = mysqli_fetch_array($result);
//echo $hashpwd."".$row["pass"];
if($row["pass"] == $hashpwd){
return $userId;
}
else{
return 0;
}
}
로그인 식별과 인증
식별이란?
- 수많은 데이터중 특정 데이터를 후레쉬로 비추는 작업.(?)
라고하기엔 이해하기가 조금 어려울수있다. 특정 데이터를 구별할 수있는 '정보' 정도로 생각하려고한다.
구별할 수있는 정보란 다른사람과 같으면 안되기때문에 그 데이터만이 가지는 특징 예를들어 아이디, 전화번호와 같은 값들이 있다. 이러한 정보들을 통해 수많은 데이터들 중에 특정 정보를 찾아낼수 있다.
$sql = "select * from test_table where name = '". $userId."'";
이러한 코딩을 통해 test_table에 있는 여러 아이디중에 원하는 데이터를 찾아낼 수 있게 된다.
인증이란?
- 그 사람이 맞는지 확인하는 작업.
식별만 하게되었다고해서 그사람에 대한 정보를 그대로 내어줄순 없게된다.
따라서 그사람이 맞는지에 대한 확인하는 과정이 필요하다.
이 과정을 '인증'이라고 한다.
$result = mysqli_query($db_conn, $sql);
$row = mysqli_fetch_array($result);
if($row['pass'] == $userPwd){
return $userId;
}
else{
return 0;
}
위의 Select 구문을 통해 데이터베이스에 저장된 그 사람의 데이터를 가져온 후
입력한 패스워드와 데이터베이스의 패스워드를 비교하여 그사람이 맞는지 '확인'할수 있게된다.
∴ 식별정보는 유출되어도 가능하다 ID,전화번호
∴ 인증정보는 유출되어서는 안된다.
∴ Hash함수를 통해 패스워드는 데이터베이스에 암호화 하여 저장.
로그인 식별/인증의 케이스들
로그인 케이스에는 여러가지 케이스가 있다.
이런 케이스들을 다 구별해야하는 이유가 뭘까 고민해보았다.
일단 예시를 4가지만 들어보겠다.
차례대로
1. 로그인 식별/인증 동시
2. 로그인 식별/인증 분리
3. 1 + hash
4. 2 + hash
<?php
function login1($userId,$userPwd){ //식별인증분리
define('DB_SERVER','localhost');
define('DB_USERNAME','admin');
define('DB_PASSWORD','student1234');
define('DB_NAME','test');
$db_conn = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_NAME);
$sql = "select * from test_table where name = '". $userId."'";
$result = mysqli_query($db_conn, $sql);
// var_dump($result); // DB 웹사이트 출력시 사용
$row = mysqli_fetch_array($result);
if($row['pass'] == $userPwd){
return $userId;
}
else{
return 0;
}
}
function login2($userId,$userPwd){ //식별인증동시
define('DB_SERVER','localhost');
define('DB_USERNAME','admin');
define('DB_PASSWORD','student1234');
define('DB_NAME','test');
$db_conn = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_NAME);
$sql = "select * from test_table where name='$userId' and pass='$userPwd'";
$result = mysqli_query($db_conn,$sql);
if($result){
return $userId;
}else{
return 0;
}
}
function login3($userId,$userPwd){ //Hash 식별인증동시
define('DB_SERVER','localhost');
define('DB_USERNAME','admin');
define('DB_PASSWORD','student1234');
define('DB_NAME','test');
$hashpwd = hash("md5",$userPwd);
$db_conn = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_NAME);
$sql = "select * from test_table where name='$userId' and pass='$hashpwd'";
$result = mysqli_query($db_conn,$sql);
if($result){
return $userId;
}
else{
return 0;
}
}
function login4($userId,$userPwd){ //Hash 식별인증분리
define('DB_SERVER','localhost');
define('DB_USERNAME','admin');
define('DB_PASSWORD','student1234');
define('DB_NAME','test');
$db_conn = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_NAME);
$hashpwd = hash("md5",$userPwd);
$sql = "select * from test_table where name='".$userId."'";
$result = mysqli_query($db_conn,$sql);
$row = mysqli_fetch_array($result);
//echo $hashpwd."".$row["pass"];
if($row["pass"] == $hashpwd){
return $userId;
}
else{
return 0;
}
}
?>
이렇게 여러가지 분리를 한 이유는 어떻게 코딩되어있는지에 따라 우회하는 기법이 다 다르게 적용된다.
SQL Injection에 대해 자세히 알진않지만.
무조건 참이되는 or '1'='1' 같은 구문과, 주석처리하는 방식등 여러가지 케이스들이 각기 다르게 적용될것같다.
해당하는 방식에 대해서는 추후 SQL Injection에 대해 공부 이후 포스팅을 하려한다.