6.1.2.4 MySQL에서 암호 해시
mysql_native_password 또는 mysql_old_password 인증 플러그인을 사용하여 계정에 적용하는 설명입니다.
MySQL에서는 mysql
데이터베이스의 user
테이블에 사용자 계정이 나열됩니다. 각 MySQL 계정에 암호를 할당 할 수 있지만, user
테이블은 암호 평문 버전을 저장하지 않고 암호에서 계산 된 해시 값을 저장합니다.
MySQL은 클라이언트와 서버의 통신의 두 단계로 암호가 사용됩니다.
클라이언트가 서버에 연결하려고하면 초기 인증 단계가 해당 단계에서는 클라이언트가 사용하는 계정에 대한
user
테이블에 저장된 해시 값과 일치하는 해시 값을 갖는 암호를 클라이언트가 제공해야합니다 .클라이언트가 연결 한 뒤, 클라이언트는 (권한이있는 경우)
user
테이블에 나열되어있는 계정에 대한 암호 해시를 설정 또는 변경할 수 있습니다. 클라이언트는PASSWORD()
함수를 사용하여 암호 해시를 생성하거나 비밀번호 생성 문 (CREATE USER
,GRANT
또는SET PASSWORD
)를 사용하여 작업을 수행 할 수 있습니다.
즉, 클라이언트가 처음에 연결하려고 할 때 서버는 인증 동안 해시 값을 검사합니다. 연결된 클라이언트가 PASSWORD()
함수를 호출하거나 암호 생성 문을 사용하여 암호를 설정하거나 변경하는 경우, 서버는 해시 값을 생성합니다.
MySQL 암호 해시 방식에는 다음 설명하기 위해 같은 역사를 가지고 있습니다. 이러한 변화는 암호 해시 값을 계산하는 PASSWORD()
함수에서의 결과와 비밀번호가 저장되는 user
테이블의 구조 변경에 의해 설명됩니다.
원래 (4.1 이전) 해시 방식
원래 해시 방식으로는 16 바이트 문자열이 생성되어있었습니다. 이러한 해시는 다음과 같이됩니다.
mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e |
+--------------------+
계정 암호를 저장하기 위해 user
테이블의 Password
컬럼이 시점에서 16 바이트 길이였습니다.
4.1 해시 방식
MySQL 4.1에서는 보안을 강화하고 암호가 유출 될 위험을 저하시키는 암호 해시가 도입되었습니다. 이 변경에는 다양한 측면이있었습니다.
PASSWORD()
함수 결과의 형식 변경Password
컬럼의 확장기본 해시 방식에 의한 제어
서버에 연결을 시도하는 클라이언트에 대해 허용 된 해시 방식에 의한 제어
MySQL 4.1의 변경은 두 단계로 이루어졌습니다.
MySQL 4.1.0에서 4.1 해시 방식의 예비 버전을 사용했습니다. 이 방식은 사용 기간이 매우 짧았 기 때문에, 이후의 설명에서 이것에 대해 언급하지 않습니다.
MySQL 4.1.1에서는 해시 방식이 변경되어 41 바이트의 긴 해시 값이 생성되게되었습니다.
mysql>
SELECT PASSWORD('mypass');
+-------------------------------------------+ | PASSWORD('mypass') | +-------------------------------------------+ | *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 | +-------------------------------------------+긴 패스워드 해시 형식은 암호화 특성이 뛰어나 긴 해시 기반 클라이언트 인증이 더 짧은 해시 기반 인증보다 보안입니다.
긴 암호 해시에 대응하기 위해,
user
테이블의Password
컬럼이 시점에서 현재의 길이 인 41 바이트로 변경되었습니다.확장 된
Password
컬럼은 4.1 이전과 4.1의 두 형식으로 암호 해시를 저장할 수 있습니다. 특정 해시 값의 형식은 두 가지 방식으로 결정됩니다.길이 : 4.1 및 4.1 이전의 해시는 각각 41 바이트와 16 바이트입니다.
4.1 형식의 패스워드 해시는 항상 '
*
'문자로 시작하지만, 4.1 이전 형식의 암호로 그렇게되는 것은 아닙니다.
4.1 이전 암호 해시를 명시 적으로 생성 할 수 있도록하기 위해 2 개의 추가 변경되었습니다.
해시 값을 16 바이트 형식으로 반환
OLD_PASSWORD()
함수가 추가되었습니다.호환성 목적으로 DBA 및 응용 프로그램이 해시 방식을 제어 할 수 있도록
old_passwords
시스템 변수가 추가되었습니다.old_passwords
값이 기본 0의 경우, 해시 4.1 방식을 사용하고 (41 바이트 해시 값)old_passwords=1
로 설정하면 해시에서 4.1 이전의 방식을 사용합니다. 이 경우,PASSWORD()
는 16 바이트 값을 생성하고OLD_PASSWORD()
와 동일합니다
클라이언트가 연결할 수있는 방법을 DBA가 제어 할 수 있도록하기 위해
secure_auth
시스템 변수가 추가되었습니다. 이 변수를 설정하거나 해제하여 서버를 시작하면 클라이언트가 4.1 이전 이전 암호 해시 방식을 사용하여 연결하는 것을 허용 또는 금지합니다. MySQL 5.6.5 이전에서는secure_auth
은 기본적으로 비활성화되어 있습니다. 5.6.5의 시점에서는보다 안전한 기본 구성을 촉진하기 위해secure_auth
은 기본적으로 활성화되어 있습니다 (DBA는 스스로의 판단에 따라이를 비활성화 할 수 있지만 이것은 권장되지 않습니다.) 4.1 이전 암호 해시는 비추천이기 때문에 사용하지 않도록하십시오. (계정 업그레이드 지침은 섹션 6.3.8.3 "4.1 이전 암호 해시 방식과 mysql_old_password 플러그인에서 마이그레이션" 을 참조하십시오.)또한 mysql 클라이언트는
secure_auth
유사한--secure-auth
옵션을 지원하지만, 이것은 클라이언트 측에서 지정합니다. 이것은 4.1 이전의 암호 해시를 사용하는 비보안 계정에 대한 연결을 방지하기 위해 사용할 수 있습니다. 이 옵션은 MySQL 5.6.7 이전에는 기본적으로 비활성화되어 있습니다 만, 그 이후로는 활성화되어 있습니다.
해시 방식에 대한 호환성 문제
MySQL 4.1에서 16 바이트에서 41 바이트의 Password
컬럼의 확장은 설치 또는 업그레이드 작업에 다음과 같이 영향을줍니다.
MySQL의 새로 설치하는 경우,
Password
컬럼은 자동적으로 41 바이트 길이입니다.MySQL 4.1 이상에서 현재 버전의 MySQL 로의 업그레이드는 두 버전 모두 동일한 컬럼 길이와 암호 해시 방식을 사용하고 있기 때문에,
Password
컬럼에 문제 아무것도 발생하지 않는 것입니다.4.1 이전 릴리스에서 4.1 이상으로 업그레이드하는 경우 업그레이드 후 시스템 테이블을 업그레이드해야합니다. ( 섹션 4.4.7 "mysql_upgrade - MySQL 테이블 체크 및 업그레이드" 를 참조하십시오.)
4.1 해시 방식은 MySQL 4.1 (이상) 서버 및 클라이언트에 의해서만 인식되기 때문에 호환성 문제가 발생할 수 있습니다. 4.1 이상의 최신 클라이언트는 4.1 이전 4.1 암호 해시 방식을 모두 인식하기 때문에 4.1 이전의 서버에 연결할 수 있습니다. 그러나 4.1 이전의 클라이언트가 4.1 이상의 최신 서버에 연결하려고하면 문제가 발생할 수 있습니다. 예를 들어, 4.0 mysql 클라이언트는 다음 오류 메시지와 함께 실패 할 수 있습니다.
shell> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
이 현상은 MySQL 4.1 이상으로 업그레이드 한 후 이전 PHP mysql
확장을 사용하려고 할 때 발생합니다. ( Common Problems with MySQL and PHP 를 참조하십시오.)
다음의 설명에서는 4.1 이전과 4.1의 해시 방식의 차이점 및 서버를 업그레이드했지만 4.1 이전 클라이언트와의 호환성을 유지해야하는 경우 어떻게해야하는지에 대해 설명합니다. (그러나 이전 클라이언트의 연결을 유지하는 것은 권장되지 않으며, 가능한 경우는 피하도록하십시오.) 섹션 B.5.2.4 "클라이언트는 인증 프로토콜에 대응할 수 없습니다" 에서 추가 정보를 찾을 수 합니다. 이 정보는 MySQL 데이터베이스를 4.1 이전 버전에서 4.1 이상으로 마이그레이션을 수행하는 PHP 프로그래머에게 특히 중요합니다.
짧은 암호 해시와 긴 패스워드 해시의 차이는 서버가 인증 중에 암호를 사용하는 방법과 암호 변경 작업을 수행하는 연결 대상 클라이언트에 서버가 암호 해시를 생성하는 방법에 모두 관계합니다 .
서버가 인증 중에 암호 해시를 사용하는 방법은 Password
컬럼의 폭에 영향을줍니다.
컬럼이 짧은 경우, 짧은 해시 인증 만 사용됩니다.
열이 긴 경우, 짧은 해시 또는 긴 해시 중 하나를 포함 할 수 있으며 서버는 하나의 형식을 사용할 수 있습니다.
4.1 이전의 클라이언트는 연결할 수 있지만 4.1 이전의 해시 방식만을 인식하기 때문에 짧은 해시를 가진 계정을 통해서만 인증 할 수 있습니다.
4.1 이상 클라이언트는 짧은 해시 또는 긴 해시를 가진 계정을 사용하여 인증 할 수 있습니다.
짧은 해시 계정도 인증 프로세스는 이전 클라이언트보다 4.1 이후의 클라이언트 쪽이 실제로 약간 보안입니다. 보안의 관점에서 안전하지 않은 것으로부터 가장 안전한 것 순으로 나열하면 다음과 같이됩니다.
짧은 암호 해시에서 인증하는 4.1 이전의 클라이언트
짧은 암호 해시에서 인증하는 4.1 이상 클라이언트
긴 패스워드 해시에서 인증하는 4.1 이상 클라이언트
연결 대상 클라이언트에 서버가 암호 해시를 생성하는 방법은 Password
컬럼의 폭과 old_passwords
시스템 변수에 영향됩니다. 4.1 이상 서버는 특정 조건이 충족 된 경우에만 긴 해시를 생성하고이 조건은 Password
컬럼이 긴 값을 유지하기위한 충분한 폭을 가질 수 및 old_passwords
가 1로 설정 되지 말라 있다는 것입니다.
이러한 조건은 다음과 같이 적용됩니다.
Password
컬럼이 긴 해시 (41 바이트)를 유지하기위한 충분한 폭을 가질 필요가 있습니다. 열이 업데이트되어 있지 않고, 4.1 이전의 16 바이트의 폭 상태 인 경우, 서버는 긴 해시가 컬럼에 맞지 않는 것을 인식하고 클라이언트가PASSWORD()
함수 또는 비밀번호 생성 문을 사용하여 비밀번호 변경 작업을 수행 할 때, 서버는 짧은 해시 만 생성합니다. 이것은 4.1 이전의 MySQL 버전에서 4.1 이상으로 업그레이드했지만,Password
컬럼을 확장하기위한 mysql_upgrade 프로그램을 아직 실행하지 않은 경우에 발생하는 동작입니다.Password
컬럼이 넓은 경우 짧은 암호 해시 또는 긴 패스워드 해시 중 하나를 저장할 수 있습니다. 이 경우 대신 짧은 암호 해시를 생성하는 것을 서버에 강제로old_passwords
시스템 변수를 1로 설정하여 서버가 시작되지 않는 한,PASSWORD()
함수와 비밀번호 생성 문은 긴 해시를 생성합니다 .
old_passwords
시스템 변수의 목적은 다른 상황에서 서버가 긴 패스워드 해시를 생성하는 상황에서 4.1 이전 클라이언트와의 호환성을 허용하는 것입니다. 이 옵션은 인증에 영향을주지 않지만 (4.1 이상 클라이언트는 긴 패스워드 해시를 가진 계정을 계속 사용할 수 있습니다) 암호 변경 작업의 결과로 user
테이블에서 긴 패스워드 해시가 생성되지 않도록합니다. 이 발생이 허용되는 경우 계정은 4.1 이전의 클라이언트에서 사용할 수 없습니다. old_passwords
을 해제하면 다음과 같은 바람직하지 않은 시나리오가 발생할 수 있습니다.
4.1 이전의 오래된 클라이언트가 짧은 암호 해시를 가진 계정에 연결합니다.
클라이언트가 자신의 암호를 변경합니다.
old_passwords
가 잘못된 경우 이로 인해 계정은 긴 암호 해시를 갖게됩니다.이전 클라이언트가 계정에 다음 접속하려고했을 때, 이전 클라이언트는 연결할 수 없습니다. 이것은 계정이 인증 과정에서 4.1 해시 방식을 필요로하는 긴 암호 해시를 가지는 것입니다. (계정이 사용자 테이블에 긴 암호 해시를 갖게되면 4.1 이전의 클라이언트는 긴 해시를 인식하지 않기 때문에 4.1 이상 클라이언트 만 인증 할 수 있습니다.)
이 시나리오에서는 4.1 이전의 오래된 클라이언트를 지원해야하는 경우 old_passwords
을 1로 설정하지 4.1 이상의 최신 서버를 실행하는 것은 문제가 있다는 것을 보여줍니다. old_passwords=1
을 사용하여 서버를 실행함으로써 암호 변경 작업은 긴 패스워드 해시를 생성하지 않고 계정이 이전 클라이언트에서 액세스 할 수없는 것은 아닙니다. (이러한 클라이언트는 자신의 비밀번호를 변경하고 긴 암호 해시를 결국 얻어서 잘못 자신을 잠금 해 버리는 것은 아닙니다.)
old_passwords=1
의 단점은 4.1 이상 클라이언트에 대해서도 만들거나 수정 된 모든 암호가 짧은 해시를 사용하는 것입니다. 즉, 긴 패스워드 해시에서 제공하는 추가 보안이 손실됩니다. 긴 해시 (예를 들어 4.1 클라이언트에서 사용하기위한 것)이있는 계정을 만들거나 긴 패스워드 해시를 사용하는 기존의 계정을 변경하기 위해 관리자는 old_passwords
세션 값을 0으로 설정 글로벌 값을 1로 설정 한 상태로 할 수 있습니다.
mysql>SET @@session.old_passwords = 0;
Query OK, 0 rows affected (0.00 sec) mysql>SELECT @@session.old_passwords, @@global.old_passwords;
+-------------------------+------------------------+ | @@session.old_passwords | @@global.old_passwords | +-------------------------+------------------------+ | 0 | 1 | +-------------------------+------------------------+ 1 row in set (0.00 sec) mysql>CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'newpass';
Query OK, 0 rows affected (0.03 sec) mysql>SET PASSWORD FOR 'existinguser'@'localhost' = PASSWORD('existingpass');
Query OK, 0 rows affected (0.00 sec)
MySQL 4.1 이상에서는 다음 시나리오가 발생할 수 있습니다. 요인은 Password
컬럼이 짧은 지 긴지하는 것으로, 긴 경우 서버가 old_passwords
를 활성화 또는 비활성화 중 지정하고 시작 했는가하는 것입니다.
시나리오 1 : 사용자 테이블의 Password
컬럼이 짧은 경우 :
Password
컬럼에게는 짧은 해시만을 저장할 수 있습니다.서버는 클라이언트 인증 중에 짧은 해시만을 사용합니다.
연결 대상 클라이언트의 경우,
PASSWORD()
함수 또는 비밀번호 생성 문을 포함하는 암호 해시 생성 조작으로 짧은 해시 만 사용됩니다. 계정의 암호를 변경 한 내용은 해당 계정은 짧은 암호 해시를 가지게됩니다.Password
컬럼이 짧은 경우, 서버는 짧은 패스워드 해시 만 생성하기 위해old_passwords
값 무관합니다.
이 시나리오는 4.1 이전의 MySQL 설치가 4.1 이상으로 업그레이드되었지만, mysql_upgrade이 아직 실행되지 않고, mysql
데이터베이스의 시스템 테이블이 업그레이드되지 않은 경우에 발생합니다. (이것은보다 안전한 4.1 암호 해시를 사용할 수 없게되기 때문에 권장되는 구성이 아닙니다.)
시나리오 2 : Password
컬럼이 길어 서버는 old_passwords=1
을 지정하여 시작되는 경우 :
Password
컬럼에게는 짧은 해시 또는 긴 해시를 저장할 수 있습니다.4.1 이상 클라이언트는 짧은 해시 또는 긴 해시를 가진 계정에 대해 인증 할 수 있습니다.
4.1 이전의 클라이언트는 짧은 해시를 가진 계정에 대해서만 인증 할 수 있습니다.
연결 대상 클라이언트의 경우,
PASSWORD()
함수 또는 비밀번호 생성 문을 포함하는 암호 해시 생성 조작으로 짧은 해시 만 사용됩니다. 계정의 암호를 변경 한 내용은 해당 계정은 짧은 암호 해시를 가지게됩니다.
이 시나리오에서는 old_passwords=1
에 의해 긴 해시를 생성 할 수 없으므로 새로 생성 된 계정은 짧은 암호 해시를 갖습니다. 또한 old_passwords
을 1로 설정하기 전에 긴 해시를 가진 계정을 만든 경우 old_passwords=1
의 경우 계정의 암호를 변경하면 계정에는 짧은 암호가 제공되어 긴 해시가 가지는 보안상의 이점 를 잃게됩니다.
긴 패스워드 해시를 가진 새 계정을 만들거나 긴 해시를 사용하는 기존의 계정을 변경하려면 앞에서 설명한 바와 같이 먼저 old_passwords
세션 값을 0으로 설정하고 글로벌 값을 1로 설정 한 채로합니다.
이 시나리오에서는 서버의 Password
컬럼은 최신 상태이지만, 서버가 4.1 이전의 해시 값을 생성하도록 기본 암호 해시 방식을 설정하여 실행됩니다. 이것은 권장되는 구성은 아니지만, 4.1 이전의 클라이언트 및 비밀번호가 4.1 이상으로 업그레이드되는 과도기에 도움이 될 수 있습니다. 이것이 완료되면 old_passwords=0
및 secure_auth=1
을 사용하여 서버를 실행하는 것이 좋습니다됩니다.
시나리오 3 : Password
컬럼이 길어 서버는 old_passwords=0
을 지정하여 시작되는 경우 :
Password
컬럼에게는 짧은 해시 또는 긴 해시를 저장할 수 있습니다.4.1 이상 클라이언트는 짧은 해시 또는 긴 해시를 가진 계정을 사용하여 인증 할 수 있습니다.
4.1 이전의 클라이언트는 짧은 해시를 가진 계정을 사용하는 경우에만 인증 할 수 있습니다.
연결 대상 클라이언트의 경우,
PASSWORD()
함수 또는 비밀번호 생성 문을 포함하는 암호 해시 생성 조작으로 긴 해시 만 사용됩니다. 계정의 암호를 변경하면 해당 계정은 긴 암호 해시를 가지게됩니다.
이전에 보여준 것처럼,이 시나리오의 위험은 짧은 암호 해시를 가진 계정이 4.1 이전의 클라이언트에서 액세스하지 못할 수 있다는 것입니다. PASSWORD()
함수 또는 비밀번호 생성 문을 사용하여 실행 한 그런 계정의 암호를 변경하여 계정에 긴 패스워드 해시가 제공되게됩니다. 그 시점 이후로는 4.1 이전 클라이언트는 해당 계정을 사용하여 서버에 연결할 수 없습니다. 클라이언트는 4.1 이상으로 업그레이드해야합니다.
이것이 문제가 될 경우 특별한 방법으로 암호를 변경 할 수 있습니다. 예를 들어 일반적으로 계정의 암호 변경은 SET PASSWORD
를 다음과 같이 사용하고 있습니다.
SET PASSWORD FOR ' some_user
'@' some_host
'= PASSWORD ('mypass ');
비밀번호를 변경할 수 있지만 짧은 해시를 생성하는 경우, 대신 OLD_PASSWORD()
함수를 사용합니다.
SET PASSWORD FOR ' some_user
'@' some_host
'= OLD_PASSWORD ('mypass ');
OLD_PASSWORD()
는 짧은 해시를 명시 적으로 생성 할 필요가있는 상황에서 유용합니다.
이전 시나리오의 단점은 다음과 같이 요약 할 수 있습니다.
시나리오 1에서는보다 안전한 인증을 제공하는 긴 해시를 활용할 수 없습니다.
시나리오 2에서는 old_passwords=1
에 의해 짧은 패스워드를 가진 계정을 액세스 할 수 할 수 없지만주의를 기울이고 old_passwords
세션 값을 먼저 0으로 변경하지 않는 한, 암호 변경 작업은 긴 해시를 가진 계정 짧은 해시에 반환됩니다.
시나리오 3에서는 짧은 해시를 사용하는 계정은 OLD_PASSWORD()
를 명시 적으로 사용하지 않고 암호를 변경 한 경우 4.1 이전 클라이언트에서 액세스 할 수 없습니다.
짧은 암호 해시에 대한 호환성 문제를 해결하는 가장 좋은 방법은 짧은 암호 해시를 사용하지 않는 방법입니다.
모든 클라이언트 프로그램을 MySQL 4.1 이상으로 업그레이드합니다.
old_passwords=0
을 지정하여 서버를 실행한다.긴 패스워드 해시를 사용하기 위해 짧은 암호 해시를 가진 모든 계정에 대한 암호를 재설정한다.
보안을 강화하기 위해
secure_auth=1
을 사용하여 서버를 실행한다.