MySQL SHA2 복호화 - MySQL SHA2 boghohwa

오래전 토이프로젝트로 시작한 소스를 리팩토링하면서 암호화 기능을 추가해봤습니다.

소스는 여기에서 확인하실 수 있습니다.


무료로 사용이 가능한 MariaDB에서는 단/양방향의 암호화 기능을 제공한다. 본문에서 사용된 암호화는 단방향으로 사용자 패스워드를 암호화할 때 사용되었다.

단방향 암호화

일반적으로 암호화는 평문을 암호문으로 바꿔주는 것을 말한다. 단방향 암호화는 평문을 암호문으로 바꾸는 것만 가능한 암호화 기법이다.

단방향 암호화는 해시 함수를 이용한다. 해시 함수는 임의의 평문 데이터를 고정된 길이의 데이터로 반환해준다. 또 동일한 값이 입력되면 동일한 출력값을 보장한다. (이 부분에 대한 위험성은 이 블로그에서 확인할 수 있었습니다)

해시 함수에는 대표적으로 MD5SHA가 있는데 일반적으로 사용되는 SHA2를 이용해 암호화를 진행했다.
MD5, SHA1은 보안성이 취약하다고 발견되어 잘 사용되지 않는다.

SHA2(str, hash_len)

  • SHA2는 MariaDB 5.5부터 도입되었다.
  • str: 임의의 평문
  • hash_len : 임의의 평문 str을 해시 함수 hash_len으로 암호화한다.. SHA-224,256,384,512 사용이 가능하다.

암호화를 적용한 테이블은 다음과 같다.

SHA256은 256bit로 64글자이기 때문에 길이는 65 정도로 지정했다.

MySQL SHA2 복호화 - MySQL SHA2 boghohwa
MySQL SHA2 복호화 - MySQL SHA2 boghohwa

현재 데이터로 들어있는 값을 보면 guest2,3,4는 암호화되어 있지 않다.

아래 쿼리문을 통해 암호화를 해보자.

UPDATE PM_USER
  SET PASSWORD = SHA2('12345', 256)
WHERE CMPCD  = 'P0001'
  AND USERID = 'guest2'
MySQL SHA2 복호화 - MySQL SHA2 boghohwa

로그인시 암호가 맞는지 체크할 때는 입력된 암호를 암호화하여 비교했다.

SELECT COUNT(USERID) AS CNT
  FROM PM_USER
 WHERE CMPCD    = 'P0001'
   AND USERID   = 'guest1'
   AND PASSWORD = SHA2('abc1234', 256)

+

양방향 암호화

양방향은 AES 대칭키 알고리즘의 암호화 기능을 사용하여 테스트를 했다.

단방향과 달리 양방향은 평문을 암호문으로 바꾼 후(이 때 암호화키가 사용된다) 다시 암호문을 암호화 키를 이용해 평문으로 바꿀 수 있다.

AES_ENCRYPT(str, key_str)

  • 암호화를 위한 기본적인 함수 포맷
  • str : 임의의 평문
  • key_str: 임의의 평문 str을 암호화 할 때 사용될 암호화키. 암호화키 사용시에도 SHA2를 이용해 암호화하는 것이 좋다.

AES_DECRYPT(str, key_str)

  • 복호화를 위한 기본적인 함수 포맷
  • str : 암호문
  • key_str : 암호문을 풀기 위한 암호화키.

이제 암호화를 해보자.

암호화키는 SHA2를 이용해 암호화했다.

AES_ENCRYPT 함수만 사용하게 되면 문자가 깨지기 때문에 문자셋을 위해 HEX함수로 한번 감싸주어야 한다.

HEX를 하게되면 16진수 값의 문자를 반환한다. 잠시 HEX에 대해 살펴보고 넘어가자.

아래는 HEX/UNHEX 사용시 결과를 보여주고 있다.

SELECT HEX('Test') T1
	  , UNHEX(HEX('Test')) T2
	  , CONVERT(UNHEX(HEX('Test')) USING UTF8) T3
  FROM PM_USER
MySQL SHA2 복호화 - MySQL SHA2 boghohwa

UNHEX는 HEX의 역산을 도와준다. 16진수를 숫자로 해석을 하고 그 숫자에 대응하는 문자로 변환한다. 그 결과, 문자들은 바이너리 스트링으로 리턴된다. 그리고 UTF8로 CONVERT 작업을 해주면 기존 텍스트로 변환이 가능하다.

다시 암호화로 돌아와서 아래 쿼리문으로 암호화/복호화를 해보자.

UPDATE PM_USER
  SET PASSWORD = HEX(AES_ENCRYPT('abc1234', SHA2('shxdb@123', 256)))
WHERE CMPCD  = 'P0001'
  AND USERID = 'guest4'
SELECT USERID
	  , PASSWORD
	  , LENGTH(PASSWORD)
	  , CONVERT(AES_DECRYPT(UNHEX(PASSWORD), SHA2('shxdb@123',256)) USING UTF8) DECPASS
  FROM PM_USER
 WHERE CMPCD = 'P0001'
MySQL SHA2 복호화 - MySQL SHA2 boghohwa
참고자료

MariaDB - SHA2 - SHA2 ()는 MariaDB 5.5 에서 도입되었습니다 Syntax Description 문자열 str 이 주어지면 SHA-2 체

Syntax SHA2(str,hash_len) Description 문자열 str 이 주어지면 SHA-2 체크섬을 계산합니다. SHA-2 체크섬은 SHA-1 동등 보다 암호화 적으로 안전한 것으로 간주됩니다 . SHA-2 제품군에는 SHA-224, SHA-256, SHA-384 및 SH

runebook.dev

패스워드의 암호화와 저장 - Hash(해시)와 Salt(솔트)

'보안은 그 어느 시스템의 정보보다 가장 중요하며 가장 안전해야 하는 것이다' 필자가 "프로그래머로써 가장 중요하게 생각해야 할 것 하나만 뽑는다면?" 이라는 질문이 들어온다면 위와 같이

st-lab.tistory.com

MySQL SHA2 복호화 - MySQL SHA2 boghohwa

MariaDB - UNHEX - Syntax Description HEX (str) 의 역 연산을 수행합니다 . 즉, 인수의 각 16 진 숫자 쌍을 숫

Syntax UNHEX(str) Description HEX (str) 의 역 연산을 수행합니다 . 즉, 인수의 각 16 진 숫자 쌍을 숫자로 해석하여 숫자로 표시되는 문자로 변환합니다. 결과 문자는 이진 문자열로 반환됩니다. 경우 str

runebook.dev

MySQL 16진수 자료형

16진수 값 MySQL은 16 진수 값을 지원한다. 숫자 문장안에서 16진수 값은 정수처럼 동작을 한다 (64-비트 표현식). 반면에, 스트링 문자에서는 바이너리 스트링처럼 동작을 하며, 각각의 16진수 쌍은

bluebreeze.co.kr

MySQL SHA2 복호화 - MySQL SHA2 boghohwa

+ 피드백은 언제나 환영입니다 :)