Verbindung Java-MySql: Das Abrufen öffentlicher Schlüssel ist nicht zulässig

104

Ich versuche, MySQL-Datenbank mit Java über Connector 8.0.11 zu verbinden. Alles scheint in Ordnung zu sein, aber ich habe diese Ausnahme:

Ausnahme im Thread "main" java.sql.SQLNonTransientConnectionException: Das Abrufen öffentlicher Schlüssel ist nicht zulässig

Stapelverfolgung:

    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)

Connector Manager:

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
quelle
1
Bitte geben Sie einen Code ein: Wie versuchen Sie, eine Verbindung herzustellen? Eine Stapelverfolgung der Ausnahme wäre ebenfalls hilfreich.
Sergei Sirik

Antworten:

224

Sie sollten Ihrem MySQL-Connector allowPublicKeyRetrieval=trueeine Client-Option hinzufügen , damit der Client den öffentlichen Schlüssel automatisch vom Server anfordern kann. Beachten Sie, AllowPublicKeyRetrieval=Truedass ein böswilliger Proxy möglicherweise einen MITM-Angriff ausführen kann, um das Klartextkennwort abzurufen. Daher ist es standardmäßig falsch und muss explizit aktiviert werden.

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

Sie können auch versuchen, etwas hinzuzufügen, useSSL=falsewenn Sie es zu Test- / Entwicklungszwecken verwenden

Beispiel:

jdbc:mysql://localhost:3306/db?allowPublicKeyRetrieval=true&useSSL=false
jtomaszk
quelle
Nun, das hat bei mir funktioniert, aber ich bin mir nicht sicher, wie legitim diese Optionen aus Sicherheitsgründen sind.
Priyank Thakkar
28
useSSL=false&allowPublicKeyRetrieval=trueist das, was ich nur brauchte, als ich versuchte, eine Verbindung von docker_container1zu docker_container2_mysql(where mysql is installed)meinem lokalen Host herzustellen . Während von meinem Host-Computer zu docker_container2_mysql, useSSL=falseist genug.
Prayagupd
1
allowPublicKeyRetrieval = true & useSSL = false, Tank du es funktioniert
Martin Klestil
2
Können Sie erklären, warum dies der Fall ist?
Capn Sparrow
Das Hinzufügen von 'allowPublicKeyRetrieval = true' zu meiner JDBC-Verbindungszeichenfolge löste das Problem meines Entwicklungssystems nach einem gestrigen Windows 10-Update. Vermutlich hat Microsoft eine weitere Lücke geschlossen, und die Option sollte meiner Ansicht nach "nur für die Entwicklung" verwendet werden, wenn SSL nicht aktiviert ist.
Alz
28

Verwendung jdbc urlals:

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

PortNo: 3306 kann in Ihrer Konfiguration unterschiedlich sein

susan097
quelle
Eine kleine Korrektur hier. Die akzeptablen Werte für die Verbindungseigenschaft 'useSSL' sind: 'TRUE', 'FALSE', 'YES' oder 'NO'. Der Wert 'false'; Das ist nicht akzeptabel.
Bluelurker
25

Für DBeaver- Benutzer:

  1. Klicken Sie mit der rechten Maustaste auf Ihre Verbindung und wählen Sie "Verbindung bearbeiten".

  2. Klicken Sie im Bildschirm "Verbindungseinstellungen" (Hauptbildschirm) auf "Treibereinstellungen bearbeiten".

  3. Klicken Sie auf "Verbindungseigenschaften"

  4. Klicken Sie mit der rechten Maustaste auf den Bereich "Benutzereigenschaften" und wählen Sie "Neue Eigenschaft hinzufügen".

  5. Fügen Sie zwei Eigenschaften hinzu: "useSSL" und "allowPublicKeyRetrieval"

  6. Setzen Sie ihre Werte auf "false" und "true", indem Sie auf die Spalte "value" doppelklicken

Javier Aviles
quelle
10

Alternativ zu den vorgeschlagenen Antworten können Sie versuchen, das Authentifizierungs-Plugin mysql_native_password anstelle des Authentifizierungs-Plugins caching_sha2_password zu verwenden .

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

Ich löse dieses Problem mithilfe der folgenden Konfiguration des Spring Boot Frameworks

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
quelle
1

In meinem Fall war es ein Benutzerfehler. Ich habe den rootBenutzer mit einem ungültigen Passwort verwendet. Ich bin nicht sicher, warum ich keinen Authentifizierungsfehler erhalten habe, sondern diese kryptische Nachricht erhalten habe.

Saft
quelle
1

Der obige Fehler in meinem Fall war tatsächlich auf den falschen Benutzernamen und das falsche Passwort zurückzuführen. Beheben des Problems: 1. Gehen Sie zur Zeile DriverManager.getConnection ("jdbc: mysql: // localhost: 3306 /? UseSSL = false", "Benutzername", "Passwort"); Die Felder Benutzername und Passwort sind möglicherweise falsch. Geben Sie den Benutzernamen und das Passwort ein, mit denen Sie Ihren MySQL-Client starten. Der Benutzername ist im Allgemeinen root und das Passwort ist die Zeichenfolge, die Sie eingeben, wenn ein ähnlicher Bildschirm angezeigt wird. Startbildschirm von mysql

Hinweis: Der Portname 3306 kann in Ihrem Fall unterschiedlich sein.

RisingStark
quelle
1

Ich fand dieses Problem frustrierend, weil ich gestern mit der Datenbank interagieren konnte, aber nachdem ich heute Morgen zurückgekommen war, bekam ich diesen Fehler.

Ich habe versucht, das hinzuzufügen allowPublicKeyRetrieval=true Flag , aber ich habe immer wieder den Fehler erhalten.

Was es für mich behoben hat, war Project->Cleanin Eclipse undClean auf meinem Tomcat-Server. Einer (oder beide) von denen haben es behoben.

Ich verstehe nicht warum, weil ich mein Projekt mit Maven erstelle und meinen Server nach jeder Codeänderung neu starte. Sehr irritierend ...

Cameron Hudson
quelle
1

Aktualisieren Sie die Verbindung useSSL = true in der Spring-Boot-Anwendung mit mysql.

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

Ich war auch mit einem solchen Problem konfrontiert, als ich unsere vorhandene Anwendung angedockt habe. Die Lösung besteht darin, die Verbindungsoption allowPublicKeyRetrieval von MySQL mit dem Wert true zur JDBC-Verbindungszeichenfolge hinzuzufügen . Wenn das nicht funktioniert, versuchen Sie , useSSL Option falsch als auch.

Die resultierende Zeichenfolge würde folgendermaßen aussehen:

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

Diese Lösung funktionierte unter MacOS Sierra und unter MySQL Version 8.0.11. Stellen Sie sicher, dass der Treiber, den Sie in Ihrem Build-Pfad hinzugefügt haben - "Add external jar" mit der SQL-Version übereinstimmen sollte.

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

Geben Sie die Verbindungs-URL als jdbc: mysql: // localhost: 3306 / hb_student_tracker an? PermitPublicKeyRetrieval = true & useSSL = false & serverTimezone = UTC

Samit Tiwary
quelle
0

Wenn beim Verbinden der MySQL die folgende Fehlermeldung angezeigt wird (entweder lokaler oder MySQL-Container, in dem die MySQL ausgeführt wird):

java.sql.SQLNonTransientConnectionException: Das Abrufen öffentlicher Schlüssel ist nicht zulässig

Lösung: Fügen Sie Ihrem Datenbankdienst die folgende Zeile hinzu:

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

Stellen Sie zunächst sicher, dass Ihr Datenbankserver betriebsbereit ist. Ich habe den gleichen Fehler erhalten, nachdem ich alle hier aufgeführten Antworten ausprobiert hatte, stellte ich fest, dass mein Datenbankserver nicht ausgeführt wurde.

Sie können dies auch über die MySQL Workbench oder die Befehlszeile mit überprüfen

mysql -u USERNAME -p

Dies klingt offensichtlich, aber wir gehen oft davon aus, dass der Datenbankserver ständig in Betrieb ist, insbesondere wenn wir an unserem lokalen Computer arbeiten. Wenn wir den Computer neu starten / herunterfahren, wird der Datenbankserver automatisch heruntergefahren.

Vinod Kumar KV
quelle