package io.vertx.mysqlclient.impl.util;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Native41Authenticator {
  
Native authentication method 'mysql_native_password' Calculate method: SHA1( password ) XOR SHA1( "20-bytes random data from server" SHA1( SHA1( password ) ) )
Params:
  • password – password value
  • charset – charset of password
  • salt – 20 byte random challenge from server
Returns:scrambled password
/** * Native authentication method 'mysql_native_password' * Calculate method: SHA1( password ) XOR SHA1( "20-bytes random data from server" <concat> SHA1( SHA1( password ) ) ) * * @param password password value * @param charset charset of password * @param salt 20 byte random challenge from server * @return scrambled password */
public static byte[] encode(String password, Charset charset, byte[] salt) { MessageDigest messageDigest; try { messageDigest = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } byte[] passwordBytes = password.getBytes(charset); // SHA1(password) byte[] passwordHash1 = messageDigest.digest(passwordBytes); messageDigest.reset(); // SHA1(SHA1(password)) byte[] passwordHash2 = messageDigest.digest(passwordHash1); messageDigest.reset(); // SHA1("20-bytes random data from server" <concat> SHA1(SHA1(password)) messageDigest.update(salt); messageDigest.update(passwordHash2); byte[] passwordHash3 = messageDigest.digest(); // result = passwordHash1 XOR passwordHash3 for (int i = 0; i < passwordHash1.length; i++) { passwordHash1[i] = (byte) (passwordHash1[i] ^ passwordHash3[i]); } return passwordHash1; } }