#### 6.4.1.3 SHA-256 可插拔身份验证

[](<>)[](<>)

MySQL 提供了两个身份验证插件，为用户帐户密码实现 SHA-256 散列：

-   `sha256_password`：实现基本的 SHA-256 身份验证。

-   `cache_sha2_password`：实现 SHA-256 身份验证（如`sha256_password`)，但在服务器端使用缓存以获得更好的性能，并具有更广泛的适用性的附加功能。

    本节介绍原始的非缓存 SHA-2 身份验证插件。有关缓存插件的信息，请参阅[第 6.4.1.2 节，“缓存 SHA-2 可插入身份验证”](caching-sha2-pluggable-authentication.html).

重要的

在 MySQL 8.0 中，`cache_sha2_password`是默认的身份验证插件，而不是`mysql_native_password`.有关此更改对服务器操作的影响以及服务器与客户端和连接器的兼容性的信息，请参阅[缓存\_沙2\_密码作为首选身份验证插件](upgrading-from-previous-series.html#upgrade-caching-sha2-password).

因为`cache_sha2_password`是 MySQL 8.0 中的默认身份验证插件，并提供了`sha256_password`身份验证插件，`sha256_password`已弃用；希望它在 MySQL 的未来版本中被删除。使用身份验证的 MySQL 帐户`sha256_password`应该迁移使用`cache_sha2_password`反而。

重要的

使用经过身份验证的帐户连接到服务器`sha256_password`插件，您必须使用 TLS 连接或支持使用 RSA 密钥对进行密码交换的未加密连接，如本节后面所述。无论哪种方式，`sha256_password`插件使用 MySQL 的加密功能。看[第 6.3 节，“使用加密连接”](encrypted-connections.html).

笔记

在名字里`sha256_password`，“sha256”是指插件用于加密的 256 位摘要长度。在名字里`cache_sha2_password`，“sha2”更一般地指的是 SHA-2 类加密算法，其中 256 位加密就是一个实例。后一个名称选择为将来扩展可能的摘要长度留出了空间，而无需更改插件名称。

下表显示了服务器端和客户端的插件名称。

[](<>)

**表 6.17 SHA-256 身份验证的插件和库名称**

| 插件或文件 | 插件或文件名 |
| ----- | ------ |
| 服务器端插件 | `sha256_password` |
| 客户端插件 | `sha256_password` |
| 库文件 | 无（内置插件） |

以下部分提供特定于 SHA-256 可插拔身份验证的安装和使用信息：

-   [安装 SHA-256 可插拔身份验证](sha256-pluggable-authentication.html#sha256-pluggable-authentication-installation)

-   [使用 SHA-256 可插拔身份验证](sha256-pluggable-authentication.html#sha256-pluggable-authentication-usage)

    有关 MySQL 中可插入身份验证的一般信息，请参阅[第 6.2.17 节，“可插拔身份验证”](pluggable-authentication.html).

##### 安装 SHA-256 可插拔身份验证

这`sha256_password`插件存在于服务器和客户端表单中：

-   服务器端插件内置在服务器中，不需要显式加载，也不能通过卸载来禁用。

-   客户端插件内置于`libmysql客户端`客户端库，可用于链接到的任何程序`libmysql客户端`.

##### 使用 SHA-256 可插拔身份验证

设置一个使用`sha256_password`SHA-256 密码哈希插件，使用以下语句，其中*`密码`*是所需的帐户密码：

```
CREATE USER 'sha256user'@'localhost'
IDENTIFIED WITH sha256_password BY 'password';
```

服务器分配`sha256_password`插件到帐户并使用它使用 SHA-256 加密密码，将这些值存储在`插入`和`身份验证字符串`的列`mysql.user`系统表。

前面的说明不假设`sha256_password`是默认的身份验证插件。如果`sha256_password`是默认的认证插件，比较简单[`创建用户`](create-user.html)可以使用语法。

使用设置为的默认身份验证插件启动服务器`sha256_password`，将这些行放在服务器选项文件中：

```
[mysqld]
default_authentication_plugin=sha256_password
```

这导致`sha256_password`插件默认用于新帐户。因此，可以在不明确命名插件的情况下创建帐户并设置其密码：

```
CREATE USER 'sha256user'@'localhost' IDENTIFIED BY 'password';
```

设置的另一个结果[`default_authentication_plugin`](server-system-variables.html#sysvar_default_authentication_plugin)到`sha256_password`也就是说，要使用其他插件来创建帐户，您必须明确指定该插件。例如，要使用`mysql_native_password`插件，使用这个语句：

```
CREATE USER 'nativeuser'@'localhost'
IDENTIFIED WITH mysql_native_password BY 'password';
```

`sha256_password`支持通过安全传输进行连接。`sha256_password`如果 MySQL 是使用 OpenSSL 编译的，并且您希望连接的 MySQL 服务器配置为支持 RSA（使用本节后面给出的 RSA 配置过程），则还支持在未加密的连接上使用 RSA 进行加密密码交换。

RSA 支持具有以下特点：

-   在服务器端，两个系统变量命名 RSA 私钥和公钥对文件：[`sha256_password_private_key_path`](server-system-variables.html#sysvar_sha256_password_private_key_path)和[`sha256_password_public_key_path`](server-system-variables.html#sysvar_sha256_password_public_key_path).如果要使用的密钥文件的名称与系统变量默认值不同，则数据库管理员必须在服务器启动时设置这些变量。

-   服务器使用[`sha256_password_auto_generate_rsa_keys`](server-system-variables.html#sysvar_sha256_password_auto_generate_rsa_keys)系统变量来确定是否自动生成 RSA 密钥对文件。看[第 6.3.3 节，“创建 SSL 和 RSA 证书和密钥”](creating-ssl-rsa-files.html).

-   这[`Rsa_public_key`](server-status-variables.html#statvar_Rsa_public_key)status 变量显示 RSA 公钥值`sha256_password`身份验证插件。

-   拥有 RSA 公钥的客户端可以在连接过程中与服务器进行基于 RSA 密钥对的密码交换，如下所述。

-   对于通过身份验证的帐户进行的连接`sha256_password`和基于RSA公钥对的密码交换，服务器根据需要将RSA公钥发送给客户端。但是，如果客户端主机上有公钥的副本，客户端可以使用它来保存客户端/服务器协议中的往返：

    -   对于这些命令行客户端，使用[`--server-public-key-path`](mysql-command-options.html#option_mysql_server-public-key-path)指定 RSA 公钥文件的选项：[**mysql**](mysql.html),[**mysql管理员**](mysqladmin.html),[**mysqlbinlog**](mysqlbinlog.html),[**mysql检查**](mysqlcheck.html),[**mysql转储**](mysqldump.html),[**mysql导入**](mysqlimport.html),[**mysql泵**](mysqlpump.html),[**mysqlshow**](mysqlshow.html),[**mysqlslap**](mysqlslap.html),**mysql测试**,[**mysql\_升级**](mysql-upgrade.html).

    -   对于使用 C API 的程序，调用[`mysql_options()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-options.html)通过传递指定 RSA 公钥文件`MYSQL_SERVER_PUBLIC_KEY`选项和文件名。

    -   对于副本，使用[`将复制源更改为`](change-replication-source-to.html)语句（来自 MySQL 8.0.23）或[`将主更改为`](change-master-to.html)语句（在 MySQL 8.0.23 之前）与`SOURCE_PUBLIC_KEY_PATH`\|`MASTER_PUBLIC_KEY_PATH`用于指定 RSA 公钥文件的选项。对于组复制，[`group_replication_recovery_get_public_key`](group-replication-options.html#sysvar_group_replication_recovery_get_public_key)系统变量具有相同的目的。

    对于使用`sha256_password`插件，连接到服务器时，密码永远不会以明文形式公开。密码传输的方式取决于使用的是安全连接还是 RSA 加密：

-   如果连接是安全的，则不需要并且不使用 RSA 密钥对。这适用于使用 TLS 加密的连接。密码以明文形式发送，但不能被窥探，因为连接是安全的。

    笔记

    不像`cache_sha2_password`， 这`sha256_password`插件不会将共享内存连接视为安全的，即使默认情况下共享内存传输是安全的。

-   如果连接不安全，并且 RSA 密钥对可用，则连接保持未加密状态。这适用于未使用 TLS 加密的连接。RSA 仅用于客户端和服务器之间的密码交换，以防止密码窥探。当服务器收到加密密码时，它会对其进行解密。在加密中使用加扰以防止重复攻击。

-   如果未使用安全连接且 RSA 加密不可用，则连接尝试将失败，因为密码无法在不以明文形式公开的情况下发送。

笔记

使用 RSA 密码加密`sha256_password`，客户端和服务器都必须使用 OpenSSL 编译，而不仅仅是其中之一。

假设 MySQL 已使用 OpenSSL 编译，请使用以下过程在客户端连接过程中启用使用 RSA 密钥对进行密码交换：

1.  使用中的说明创建 RSA 私钥和公钥对文件[第 6.3.3 节，“创建 SSL 和 RSA 证书和密钥”](creating-ssl-rsa-files.html).

2.  如果私钥和公钥文件位于数据目录中并命名为`private_key.pem`和`public_key.pem`（的默认值[`sha256_password_private_key_path`](server-system-variables.html#sysvar_sha256_password_private_key_path)和[`sha256_password_public_key_path`](server-system-variables.html#sysvar_sha256_password_public_key_path)系统变量），服务器在启动时自动使用它们。

    否则，要显式命名密钥文件，请将系统变量设置为服务器选项文件中的密钥文件名。如果文件位于服务器数据目录中，则无需指定它们的完整路径名：

    ```
    [mysqld]
    sha256_password_private_key_path=myprivkey.pem
    sha256_password_public_key_path=mypubkey.pem
    ```

    如果密钥文件不在数据目录中，或者要在系统变量值中明确显示它们的位置，请使用完整路径名：

    ```
    [mysqld]
    sha256_password_private_key_path=/usr/local/mysql/myprivkey.pem
    sha256_password_public_key_path=/usr/local/mysql/mypubkey.pem
    ```

3.  重新启动服务器，然后连接到它并检查[`Rsa_public_key`](server-status-variables.html#statvar_Rsa_public_key)状态变量值。实际显示的值与此处显示的不同，但应为非空：

    ```
    mysql> SHOW STATUS LIKE 'Rsa_public_key'\G
    *************************** 1. row ***************************
    Variable_name: Rsa_public_key
            Value: -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUDd+KvSZgY7cNBZMNpwX6
    MvE1PbJFXO7u18nJ9lwc99Du/E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz/ckaaJa
    aLgJOBCIDmNVnyU54OT/1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ
    g8aV7EtKwyhHb0c30QIDAQAB
    -----END PUBLIC KEY-----
    ```

    如果该值为空，则服务器发现密钥文件存在问题。检查错误日志以获取诊断信息。

    使用 RSA 密钥文件配置服务器后，通过`sha256_password`插件可以选择使用这些密钥文件连接到服务器。如前所述，此类帐户可以使用安全连接（在这种情况下不使用 RSA）或使用 RSA 执行密码交换的未加密连接。假设使用未加密的连接。例如：


```
$> mysql --ssl-mode=DISABLED -u sha256user -p
Enter password: password
```

对于此连接尝试`sha256user`，服务器确定`sha256_password`是适当的身份验证插件并调用它（因为那是在[`创建用户`](create-user.html)时间）。该插件发现连接未加密，因此需要使用 RSA 加密传输密码。在这种情况下，插件将 RSA 公钥发送给客户端，客户端使用它来加密密码并将结果返回给服务器。该插件使用服务器端的 RSA 私钥对密码进行解密，并根据密码是否正确接受或拒绝连接。

服务器根据需要将 RSA 公钥发送给客户端。但是，如果客户端有一个文件包含服务器所需的 RSA 公钥的本地副本，它可以使用[`--server-public-key-path`](mysql-command-options.html#option_mysql_server-public-key-path)选项：

```
$> mysql --ssl-mode=DISABLED -u sha256user -p --server-public-key-path=file_name
Enter password: password
```

文件中的公钥值由[`--server-public-key-path`](mysql-command-options.html#option_mysql_server-public-key-path)选项应该与服务器端文件中的键值相同[`sha256_password_public_key_path`](server-system-variables.html#sysvar_sha256_password_public_key_path)系统变量。如果密钥文件包含有效的公钥值但该值不正确，则会出现拒绝访问错误。如果密钥文件不包含有效的公钥，则客户端程序无法使用它。在这种情况下，`sha256_password`插件将公钥发送给客户端，就好像没有[`--server-public-key-path`](mysql-command-options.html#option_mysql_server-public-key-path)已指定选项。

客户端用户可以通过两种方式获取 RSA 公钥：

-   数据库管理员可以提供公钥文件的副本。

-   可以通过其他方式连接到服务器的客户端用户可以使用`显示状态像'Rsa_public_key'`语句并将返回的键值保存在文件中。
