MySQL 이용 AESENCRYPT()와 AESDECRYPT()복호화 의 정확 한 방법 예시

머리말
최근 작업 중 에 필요 한 것 이 있 습 니 다.AES_ENCRYPT()함 수 를 사용 하여 명문 을 암호 화하 여 MySQL 에 저장 해 야 하 는데 문제 가 생 겼 습 니 다.다음은 상세 하 게 소개 하 겠 습 니 다.
암호 화 된 밀 문 을 복호화 해서 꺼 내 면 NULL 이 라 고 합 니 다.
그녀 가 보 낸 시계 구 조 를 보 았 다.

다시 봤 어 요.AES 를 통 해서...DECRYPT()함수 가 문자열 을 암호 화하 고 insert 가 들 어 갔 습 니 다.실행 에 성공 하면 하나 가 표 시 됩 니 다warning:
Query OK, 1 row affected, 1 warning (0.00 sec)
(잘못 알 리 지 않 고 warning 입 니 다.아마 sql모드
이때 그녀 는 이 warning 을 무시 하고AES_DECRYPT()을 통 해 복호화 한 후에 꺼 낸 명문 이 NULL 이라는 것 을 발견 했다.
표 구 조 를 다시 보면 필드 속성 이'varchar'&&문자 집합 은 ut8 이 고 warning 을 다음 으로 검사 합 니 다.

mysql> show warnings;
+---------+------+------------------------------------------------------------------------+
| Level | Code | Message        |
+---------+------+------------------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\xE3f767\x12...' for column 'passwd' at row 1 |
+---------+------+------------------------------------------------------------------------+
1 row in set (0.00 sec)
문 서 를 찾 아 보 았 습 니 다.이 두 함수 의 사용 을 보 세 요.

--  'hello world'  ,   'key',       @pass 
mysql> SET @pass=AES_ENCRYPT('hello world', 'key'); 
Query OK, 0 rows affected (0.00 sec)

--           (  2     )
mysql> SELECT CHAR_LENGTH(@pass);
+--------------------+
| CHAR_LENGTH(@pass) |
+--------------------+
| 16   |
+--------------------+
1 row in set (0.00 sec)

--   AES_DECRYPT()  
mysql> SELECT AES_DECRYPT(@pass, 'key');
+---------------------------+
| AES_DECRYPT(@pass, 'key') |
+---------------------------+
| hello world  |
+---------------------------+
1 row in set (0.00 sec)
그럼 어떻게 저장 해 야 하나 요?
방법 ①:
필드 속성 을 varbinary/binary/네 개의 blob 형식 등 바 이 너 리 필드 속성 으로 설정 합 니 다.
세 필드 를 만 듭 니 다.속성 은 각각 varbinary,binary,blob 입 니 다.
그리고'명문 1','text 2','명문text 3'암호 화,키 는 key 로 표 에 저장 합 니 다.
마지막 으로 꺼 내.

mysql> CREATE TABLE t_passwd (pass1 varbinary(16), pass2 binary(16), pass3 blob);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t_passwd VALUES (AES_ENCRYPT('  1', 'key'), AES_ENCRYPT('text2', 'key'), AES_ENCRYPT('  _text3', 'key')); 
Query OK, 1 row affected (0.01 sec)

mysql> SELECT AES_DECRYPT(pass1, 'key'), AES_DECRYPT(pass2, 'key'), AES_DECRYPT(pass3, 'key') FROM t_passwd;
+---------------------------+---------------------------+---------------------------+
| AES_DECRYPT(pass1, 'key') | AES_DECRYPT(pass2, 'key') | AES_DECRYPT(pass3, 'key') |
+---------------------------+---------------------------+---------------------------+
|   1   | text2   |   _text3   |
+---------------------------+---------------------------+---------------------------+
1 row in set (0.00 sec)
물론 속성 괄호 안의 길 이 는 명문 의 길이 에 달 려 있 고 여기 에는 명문 이 비교적 짧 기 때문에 16 만 주 었 다.
방법 ②:
밀 문 16 진 을 varchar/char 열 에 저장 합 니 다.
HEX()로 저장 하고UNHEX()로 꺼 내야 합 니 다.
문자열 속성의 필드 를 만 듭 니 다.
'hello world'를 먼저 키'key 2'로 AES 암호 화 한 다음 에 암호 화 된 문자열 을 HEX 함수 16 진수 로 바 꿉 니 다.
마지막 으로 암호 화 된 문자열 을 UNHEX 를 통 해 꺼 낸 다음 AES 키'key 2'를 통 해 복호화 합 니 다.

mysql> CREATE TABLE t_passwd_2(pass1 char(32));
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t_passwd_2 VALUES (HEX(AES_ENCRYPT('hello world', 'key2')));
Query OK, 1 row affected (0.00 sec)

mysql> SELECT AES_DECRYPT(UNHEX(pass1), 'key2') FROM t_passwd_2; 
+-----------------------------------+
| AES_DECRYPT(UNHEX(pass1), 'key2') |
+-----------------------------------+
| hello world   |
+-----------------------------------+
1 row in set (0.00 sec)
마찬가지 로 명문 의 길이 에 따라 AESENCRYPT 암호 화 된 문자열 의 길이 도 달라 지기 때문에 HEX 이후 문자열 의 길이 도 달라 집 니 다.
실제 사용 시 업무 평가 에 따라 합 리 적 인 가 치 를 평가 하면 된다.
방법 ③:
varchar 에 직접 저장 하고 16 진법 으로 하지 않 습 니 다.
문제 의 시작 을 거 슬러 올 라 가면 암호 화 된 문자열 을 utf 8 문자 집합 에 저장 하고 속성 은 varchar 에 저장 하면 안 됩 니 다.
실제로 문자 집합 을 latin 1 로 바 꾸 면 됩 니 다.
insert 때 도 warning 을 알 리 지 않 을 겁 니 다.

mysql> CREATE TABLE t_passwd_3(pass varchar(32)) CHARSET latin1;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t_passwd_3 SELECT AES_ENCRYPT('text', 'key3');
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> SELECT AES_DECRYPT(pass, 'key3') FROM t_passwd_3;
+---------------------------+
| AES_DECRYPT(pass, 'key3') |
+---------------------------+
| text   |
+---------------------------+
1 row in set (0.00 sec)
이러한 방법 은 아름 답지 만 필드 문자 집합 을 latin 1 로 설정 하면 되 지만 위험 을 가 져 올 수 있 습 니 다.
문서 에 다음 과 같은 문장 이 쓰 여 있다.
Many encryption and compression functions return strings for which the result might contain arbitrary byte values. If you want to store these results, use a column with a VARBINARY or BLOB binary string data type. This will avoid potential problems with trailing space removal or character set conversion that would change data values, such as may occur if you use a nonbinary string data type (CHAR, VARCHAR, TEXT).
대 의 는 ③ 방법 을 사용 하면 암호 화 된 문자열 을 char/varchar/text 형식 에 직접 저장 하고 문자 변환 을 할 때 나 빈 칸 이 삭 제 될 때 잠재 적 인 영향 을 미 칠 수 있다 는 것 이다.
그래서 char/varchar/text 에 꼭 존재 해 야 한다 면 방법 ②,16 진법 을 참고 하 세 요.
또는 방법 ① 과 같이 바 이 너 리 필드 에 직접 존재 합 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
참고 문서:
Chapter 12 Functions and Operators - 12.13 Encryption and Compression Functions

좋은 웹페이지 즐겨찾기