TIL (2020.06.16)

Awesome·2020년 6월 17일
0

TIL

목록 보기
15/46

Mysql

mysql 을 사용하는 데에 있어서 알아두어야 할 간단한 명령어들을 익혀두자.

  1. DDL(Data Define Language)
    CREATE / ALTER / DROP

1) 데이터 베이스 생성 구문

CREATE DATABASE [database name] CHARACTER SET [character set];

CREATE DATABASE mysql_test CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

2) 테이블 작성/변경/삭제

Syntax

CREATE TABLE [table] (column1, column2 …)
ex) CREATE TABLE books (id INT NOT NULL, name varchar(30))
ALTER TABLE [table] ADD [column][datatype]
DROP TABLE [table];

  1. DML(Data Manipulation Language)
    INSERT / DELETE / UPDATE

Syntax

INSERT INTO [table] VALUES (value1, value2, value3…)
SELECT * FROM [table];
DELETE FROM [table] WHERE [condition]
UPDATE [table] SET [column]=[value] WHERE [condition]

그 외의 기타 구문

SHOW DATABASES;
SHOW TABLES;
SELECT @@AUTOCOMMIT;

SET foreign_key_checks = 0;
DROP [table]
SET foreign_key_checks = 1;

  1. TCL(Transaction Control Language)
    COMMIT / CALLBACK

Syntax

SET AUTOCOMMIT=0 or START TRANSACTION

Mysql 에서 default로 autocommit = 1(True) 이므로 TCL이 적용되지 않는다. autocommit 은 자동으로 커밋(변경사항을 DB에 반영) 하는 명령어다. 따라서 autocommit을 해제하거나 TCL을 사용할때마다 매번 START TRANSACTION 을 해줘야 한다.

COMMIT;
ROLLBACK;
SAVEPOINT 포인터명;
ROLLBACK TO 포인터명;

  • COMMIT : 변동사항을 DB 에 반영
  • ROLLBACK : COMMIT 직전 단계로 돌아감
  • SAVEPOINT : 특정 저장 지점을 설정함
  • ROLLBACK TO ~ : SAVEPOINT 지점으로 돌아감
    ** AUTOCOMMIT 해제가 안된 경우에는 각 TCL을 사용할 때마다 START TRANSACTION 명령을 수행해야 함!

Bcrypt / JWT

Bcrypt

어제 해시함수 관련 포스팅에 이어서 실제로 salting과 추가로 key streching을 적용한 패스워드 암호화를 구현해보자.

우선, key streching 에 대해 알아보자.
Key streching 은 salting 된 패스워드를 여러 차례 해시 값으로 만드는 것이다. 해시 함수에 반복적으로 돌린 횟수만큼 패스워드 일치 여부를 판단하기 위해서도 해시 함수를 돌려야 한다.

일반적으로는 하나의 패스워드를 확인하기 위해서는 한 번만 수행하면 되므로 0.2초 정도의 시간이 문제가 되지 않지만, 해킹을 목적으로 한다면 0.2초가 수행되는 작업을 5번만 수행해도 1초가 소요된다.

매우 짧게 느껴질 수 있으나 key streching 되어있지 않은 경우에는 1초에 50억개의 값을 비교해볼 수 있었던 것에 비해 소요 시간이 굉장히 늘어났다.

그럼 이제 직접 수행해보자.

import bcrypt

password = "1234"
bcrypt.hashpw(password.encode('utf-8', bcrypt.gensalt())

> b'2b$12$rP7KR4eWkUfvFlf6SCrxZO42qo/AGfnOlbyEFrrUUO2doSKY.Gfxi

위와 같이 salt를 생성하고 default로 12회 정도 key streching 된다.
결과는 bytes 형태로 나타난다.

이렇게 암호화된 데이터를 DB에 저장하고, 해당 값과 실제 유저가 입력한 값을 비교한다. 어떻게 비교할까?

암호화될 때, salt 부분은 고정된다. 즉, 매번 bcrypt.gensalt() 를 하면 salt 가 계속 바뀌겠지만, 한 번 만든 salt를 여러 패스워드에 동일하게 붙여쓰면 salt 부분은 변함이 없다.

salt = bcrypt.gensalt()
bcrypt.hashpw("1234".encode('utf-8'), salt)

>$2b$12$HZtCV2e25C6MpfkH.IkPUONDMul // f4HcIPWod.oqXLf6Ci6FkwVeuu

bcrypt.hashpw("123".encode('utf-8'), salt)
>$2b$12$HZtCV2e25C6MpfkH.IkPUONDMul // 41vLRjsdPM1w0fnGUp6pbXzN21

유저의 input이 달라졌지만 salt를 동일하게 사용했으므로, 암호화된 데이터의 salt 부분은 동일하다.

그럼 오히려 salt를 제외한 부분만 떼서 복호화하면 원래 키 값이 나오는거 아닌가??

그렇지 않다. 암호화된 결과물은 salt + key 에 대한 결과이므로 salt 뒷 부분만으로 원래 키 값을 추정하는 것은 불가능하다.

패스워드의 일치여부는 checkpw method를 통해서 가능하다.

bcrypt.checkpw("1234".encode('utf-8'), hashed_pw))
> True

JWT(Json Web Token)

회원정보를 확인하고 로그인이 성공한 후에는 매번 회원정보를 비교하지 않고, 암호화된 json 형태의 토큰을 저장한다. 암호화를 하는 이유는 쿠키나 세션에 회원정보가 노출되면 쉽게 유출될 수 있기 때문이다.

JWT는 위와 같이 header.payload.signature 로 구성되어 있다.
header 에는 토큰의 타입과 암호화 알고리즘을 담는다. payload는 실제 유저인지를 판별할 수 있는 정보를 담는다. 마지막으로 signature는 header와 payload를 인코딩하여 해시처리한 암호화 값이 담긴다.

import jwt
access_token = jwt.encode({"user_id":2},"secret",algorithm="HS256")
> Xpwjfkds.1231j.siejSVHJER38cmsl3.c29s1jfdLS/se

jwt.decde(access_token, "secret", algorithm="HS256")
> {"user_id":2}
profile
keep calm and carry on

0개의 댓글