Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

sql.mysql.auth

import sql.mysql.auth

sql lifts part of this module out to its own top level; each name below is shown with the path that reaches it. Anything still spelled sql.mysql.auth.* needs import sql.mysql.auth.

The authentication plugins a MySQL or MariaDB server can ask for.

Every one of them works from the same starting point: the server sends a random scramble in its greeting, and the client answers with something that proves it knows the password without containing it. What differs is the proof.

PluginProof
mysql_native_passwordSHA-1 of the password, masked with the scramble.
caching_sha2_passwordThe same in SHA-256, with a fallback for an uncached password.
sha256_passwordThe password itself, under TLS or RSA.
client_ed25519A signature over the scramble, by a key derived from the password.
mysql_clear_passwordThe password itself. Refused unless the connection is private.

The two that send the password

sha256_password and the slow half of caching_sha2_password send the password rather than a proof, because the server needs it to compute the hash it will cache. That is safe over TLS and over a unix socket, and over neither otherwise, so on a plain TCP connection the password is encrypted to a public key the server hands over first. mysql_clear_password has no such fallback and is refused on a connection that is not already private.

Constants

NATIVE

sql.mysql.NATIVE = 'mysql_native_password'

MySQL’s original plugin, and still MariaDB’s default.

CACHING_SHA2

sql.mysql.CACHING_SHA2 = 'caching_sha2_password'

The default since MySQL 8.0.

SHA256

sql.mysql.SHA256 = 'sha256_password'

MySQL 5.7’s stronger option, superseded by the caching one.

CLEAR

sql.mysql.CLEAR = 'mysql_clear_password'

Sends the password as it is. Needs a private connection.

ED25519

sql.mysql.ED25519 = 'client_ed25519'

MariaDB’s signature-based plugin.

NONE

sql.mysql.auth.NONE = 'mysql_old_password'

Named in a handshake by a server that wants no password at all.

SUPPORTED

sql.mysql.auth.SUPPORTED = [...]

The plugins this adapter can answer.

Functions

supports()

sql.mysql.auth.supports(plugin: string) -> bool

Whether plugin is one this adapter knows how to answer.

Parameters

  • plugin (string)

Returns bool

native_password()

sql.mysql.auth.native_password(password: string, scramble) -> bytes

The mysql_native_password response.

The server stores SHA-1 of SHA-1 of the password. Hashing the scramble together with what the server stores produces a mask that both sides can compute, and the client returns its own first stage hash under that mask. The server unmasks it, hashes it once more, and compares. The password never crosses the wire and neither does anything that would work a second time.

Parameters

  • password (string)
  • scramble (bytes) — The 20 bytes from the greeting.

Returns bytes — The 20 byte response, or nothing for an empty password, which is what the server expects for an account with none.

caching_sha2_password()

sql.mysql.auth.caching_sha2_password(password: string, scramble) -> bytes

The fast caching_sha2_password response.

The same construction in SHA-256, with the scramble on the other side of the hash. It only succeeds where the server already holds this account’s hash in memory; a server that does not answers with a request for the password itself.

Parameters

  • password (string)
  • scramble (bytes)

Returns bytes — The 32 byte response, or nothing for an empty password.

ed25519_password()

sql.mysql.auth.ed25519_password(password: string, scramble) -> bytes

The client_ed25519 response, which MariaDB uses.

The password is hashed into an Ed25519 key and the scramble is signed with it. The server holds only the matching public key, so unlike every hash based plugin here, what the server stores cannot be replayed against it.

Parameters

  • password (string)
  • scramble (bytes)

Returns bytes — The 64 byte signature.

clear_password()

sql.mysql.auth.clear_password(password: string) -> bytes

The password as the server reads it when it is sent outright: the bytes and the zero that ends them.

Parameters

  • password (string)

Returns bytes

obfuscate()

sql.mysql.auth.obfuscate(password: string, scramble) -> bytes

The password masked with the scramble, which is the form the two RSA plugins encrypt.

Masking adds nothing against someone who can read the ciphertext, since they cannot. It matters because the scramble differs every connection, so the same password never encrypts to the same bytes twice, and a captured exchange cannot be replayed.

Parameters

  • password (string)
  • scramble (bytes)

Returns bytes

encrypt_password()

sql.mysql.auth.encrypt_password(password: string, scramble, public_pem: string) -> bytes

The password encrypted to the server’s public key, for the plugins that need the password itself over a connection that is not private.

MySQL decrypts this with OAEP under SHA-1, which is what its own server links against. The choice is the server’s, not this adapter’s.

Parameters

  • password (string)
  • scramble (bytes)
  • public_pem (string) — The key the server sent.

Returns bytes

Raises AuthenticationError if the key will not parse.

response_for()

sql.mysql.auth.response_for(plugin: string, password: string, scramble, private: bool) -> bytes

The first response to send for plugin, before any back and forth.

Parameters

  • plugin (string)
  • password (string)
  • scramble (bytes)
  • private (bool) — Whether the connection is already private, which decides whether a plugin may send the password outright.

Returns bytes

Raises AuthenticationError if the plugin is one this adapter cannot answer, or would have to answer unsafely.


2026, Richard Ore and Zuri contributors