Conexión Java-MySql: no se permite la recuperación de claves públicas

105

Intento conectar la base de datos MySql con Java usando el conector 8.0.11. Todo parece estar bien, pero tengo esta excepción:

Excepción en el hilo "principal" java.sql.SQLNonTransientConnectionException: No se permite la recuperación de clave pública

Seguimiento de pila:

    Exception in thread "main" java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:108) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at 
 com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862) at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:444) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226) at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:438) at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:146) at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:119) at ConnectionManager.getConnection(ConnectionManager.java:28) at Main.main(Main.java:8)

Administrador de conectores:

public class ConnectionManager {

    public static final String serverTimeZone = "UTC";
    public static final String serverName = "localhost";
    public static final String databaseName ="biblioteka";
    public static final int portNumber = 3306;
    public static final String user = "anyroot";
    public static final String password = "anyroot";

    public static Connection getConnection() throws SQLException {

        MysqlDataSource dataSource = new MysqlDataSource();

        dataSource.setUseSSL( false );
        dataSource.setServerTimezone( serverTimeZone );
        dataSource.setServerName( serverName );
        dataSource.setDatabaseName( databaseName );
        dataSource.setPortNumber( portNumber );
        dataSource.setUser( user );
        dataSource.setPassword( password );

        return dataSource.getConnection();
    }
}
danny
fuente
1
Por favor, proporcione un código: ¿cómo está intentando conectarse? El seguimiento de la pila de la excepción también sería útil.
Sergei Sirik

Respuestas:

230

Debe agregar la opción de cliente a su conector mysql allowPublicKeyRetrieval=truepara permitir que el cliente solicite automáticamente la clave pública del servidor. Tenga en cuenta que AllowPublicKeyRetrieval=Truepodría permitir que un proxy malintencionado realice un ataque MITM para obtener la contraseña de texto sin formato, por lo que es Falsa de forma predeterminada y debe habilitarse explícitamente.

https://mysql-net.github.io/MySqlConnector/connection-options/

También puede intentar agregar useSSL=falsecuando lo use para probar / desarrollar propósitos

ejemplo:

jdbc:mysql://localhost:3306/db?allowPublicKeyRetrieval=true&useSSL=false
jtomaszk
fuente
1
Bueno, esto funcionó para mí, pero no estoy seguro de cuán legítimas son estas opciones desde la perspectiva de la seguridad.
Priyank Thakkar
28
useSSL=false&allowPublicKeyRetrieval=truees lo que necesitaba sólo cuando traté de conectar docker_container1a docker_container2_mysql(where mysql is installed)dentro de mi máquina local. Mientras que desde mi máquina host hasta docker_container2_mysql, useSSL=falsees suficiente.
prayagupd
1
allowPublicKeyRetrieval = true & amp; useSSL = false, cuéntanos que funciona
Martin Klestil
2
¿Puede explicar por qué es así?
Capn Sparrow
Agregar 'allowPublicKeyRetrieval = true' a mi cadena de conexión JDBC resolvió el problema de mi sistema de desarrollo después de una actualización de Windows 10 ayer. Supongo que Microsoft tapó otro agujero, y la opción debería usarse "solo para desarrollo" en mi opinión, donde SSL no está activado.
Alz
30

Utilizar jdbc urlcomo:

jdbc:mysql://localhost:3306/Database_dbName?allowPublicKeyRetrieval=true&useSSL=false;

PortNo: 3306 puede ser diferente en tu configuración

susan097
fuente
Una pequeña corrección aquí. Los valores aceptables de la propiedad de conexión 'useSSL' son: 'TRUE', 'FALSE', 'YES' o 'NO'. El valor 'falso'; no es aceptable.
bluelurker
27

Para usuarios de DBeaver :

  1. Haga clic derecho en su conexión, elija "Editar conexión"

  2. En la pantalla "Configuración de conexión" (pantalla principal), haga clic en "Editar configuración del controlador"

  3. Haga clic en "Propiedades de conexión"

  4. Haga clic con el botón derecho en el área "propiedades del usuario" y seleccione "Agregar nueva propiedad"

  5. Agrega dos propiedades: "useSSL" y "allowPublicKeyRetrieval"

  6. Establezca sus valores en "falso" y "verdadero" haciendo doble clic en la columna "valor"

Javier Avilés
fuente
10

Alternativamente a las respuestas sugeridas, puede intentar usar el complemento de autenticación mysql_native_password en lugar del complemento de autenticación caching_sha2_password .

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here'; 
Torsten Ojaperv
fuente
4

Resuelvo este problema usando la siguiente configuración en el marco de arranque de primavera

spring.datasource.url=jdbc:mysql://localhost:3306/db-name?useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
shellhub
fuente
1

En mi caso fue un error del usuario. Estaba usando al rootusuario con una contraseña no válida. No estoy seguro de por qué no recibí un error de autenticación, sino que recibí este mensaje críptico.

jugo
fuente
1

El error anterior en mi caso se debió en realidad a un nombre de usuario y contraseña incorrectos. Resolviendo el problema: 1. Vaya a la línea DriverManager.getConnection ("jdbc: mysql: // localhost: 3306 /? UseSSL = false", "username", "password"); Es posible que los campos nombre de usuario y contraseña sean incorrectos. Ingrese el nombre de usuario y la contraseña que usa para iniciar su cliente mysql. El nombre de usuario es generalmente root y la contraseña es la cadena que ingresa cuando aparece una pantalla similar a esta Pantalla de inicio de mysql

Nota: El nombre de puerto 3306 puede ser diferente en su caso.

RisingStark
fuente
1

Encontré este problema frustrante porque ayer pude interactuar con la base de datos, pero después de regresar esta mañana, comencé a recibir este error.

Intenté agregar la allowPublicKeyRetrieval=truebandera, pero seguí recibiendo el error.

Lo que me solucionó fue Project->Cleanen Eclipse y Cleanen mi servidor Tomcat. Uno (o ambos) de los que lo arreglaron.

No entiendo por qué, porque construyo mi proyecto usando Maven y he estado reiniciando mi servidor después de cada cambio de código. Muy irritante ...

Cameron Hudson
fuente
1

Actualice useSSL = true en la conexión de la aplicación de arranque de primavera con mysql;

jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Bheem Singh
fuente
1

También estaba enfrentando un problema de este tipo mientras acoplaba nuestra aplicación existente. La solución si agregar opción de conexión allowPublicKeyRetrieval de MySQL con un valor verdadero para la cadena de conexión JDBC. Si eso no funciona, intente agregar la opción useSSL a falso también.

La cadena resultante se vería así:

jdbc:mysql://<database server ip>:3306/databaseName?allowPublicKeyRetrieval=true&useSSL=false
Arun s
fuente
0

Esta solución funcionó para MacOS Sierra y ejecutó MySQL versión 8.0.11. Asegúrese de que el controlador que ha agregado en su ruta de compilación - "agregar jar externo" debe coincidir con la versión SQL.

String url = "jdbc:mysql://localhost:3306/syscharacterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
surendrapanday
fuente
0

Proporcione la URL de conexión como jdbc: mysql: // localhost: 3306 / hb_student_tracker? AllowPublicKeyRetrieval = true & useSSL = false & serverTimezone = UTC

samit tiwary
fuente
0

Si recibe el siguiente error al conectar mysql (ya sea un contenedor local o mysql que ejecuta mysql):

java.sql.SQLNonTransientConnectionException: no se permite la recuperación de clave pública

Solución: agregue la siguiente línea en su servicio de base de datos:

command: --default-authentication-plugin=mysql_native_password
Rohtash Singh Lakra
fuente
0

En primer lugar, asegúrese de que su servidor de base de datos esté funcionando. Recibía el mismo error, después de probar todas las respuestas enumeradas aquí, descubrí que mi servidor de base de datos no se estaba ejecutando.

Puede verificar lo mismo desde MySQL Workbench o desde la línea de comandos usando

mysql -u USERNAME -p

Esto suena obvio, pero muchas veces asumimos que el servidor de la base de datos está funcionando todo el tiempo, especialmente cuando estamos trabajando en nuestra máquina local, cuando reiniciamos / apagamos la máquina, el servidor de la base de datos se cerrará automáticamente.

Vinod Kumar KV
fuente