web-dev-qa-db-fra.com

SSL Java java.io.IOException: format de fichier de clés non valide

Je teste SSL en Java avec SSLServerSocket et d'autres classes du package Java.ssl. Lorsque j'exécute le code suivant, j'obtiens l'exception Java.io.IOException: format de fichier de clés non valide. Mon code:

package testing;
import Java.io.BufferedReader;
import Java.io.FileInputStream;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.io.PrintWriter;
import Java.net.Socket;
import Java.security.KeyStore;

import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManager;

public class SSLServerTest {
    public static void main(String[] args) {
        try {
            int port = 3000;
            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            KeyStore ks = KeyStore.getInstance("JKS");
            InputStream ksIs = new FileInputStream("key.txt");
            try {
                ks.load(ksIs, "Bennett556".toCharArray());
            } finally {
                if (ksIs != null) {
                    ksIs.close();
                }
            }
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, "Bennett556".toCharArray());
            sc.init(kmf.getKeyManagers(), new TrustManager[] {}, null);
            ServerSocketFactory ssocketFactory = sc.getServerSocketFactory();
            SSLServerSocket ssocket = (SSLServerSocket) ssocketFactory
                    .createServerSocket(port);
            ssocket.setEnabledProtocols(new String[] { "SSLv3" });
            Socket socket = ssocket.accept();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            out.println("Hello, Securly!");
            out.close();
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Fichier key.txt: 1268312345812304612348712634283427346 Je suppose que je devrais ajouter autre chose dans le fichier key.txt, mais je ne sais pas quoi y mettre. Probablement un objet searilized.

EDIT: Code client:

package testing;
import Java.io.BufferedReader;
import Java.io.FileInputStream;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.security.KeyStore;

import javax.net.SocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;

public class SSLClientTest {
    public static void main(String[] args) {

        int port = 3000;
        String Host = "localhost";

        try {
            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            KeyStore ks = KeyStore.getInstance("JKS");
            InputStream ksIs = new FileInputStream("key.txt");
            try {
                ks.load(ksIs, "Bennett556".toCharArray());
            } finally {
                if (ksIs != null) {
                    ksIs.close();
                }
            }
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, "Bennett556".toCharArray());
            sc.init(kmf.getKeyManagers(), new TrustManager[] {}, null);
            SocketFactory factory = sc.getSocketFactory();
            SSLSocket socket = (SSLSocket) factory.createSocket(Host, port);
            socket.startHandshake();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            String str = "";
            while ((str = in.readLine()) != null)
                System.out.println(str);
            in.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
9
Java Is Cool

Votre fichier est invalide. Vous devez importer un fichier de clés JKS et non un fichier txt. Vous devez utiliser keytool pour créer votre fichier de magasin de clés, puis importer ce fichier.

7
VGe0rge

J'ai eu exactement le même problème. En effet, le fichier de clés n'était pas valide et n'était pas lié à la version de JDK // JRE. Le problème dans mon cas a été causé par Maven. J'utilisais l'option suivante dans mon fichier pom:

<resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

La valeur "true" dans le filtrage déconnait le fichier de clé. Par conséquent, le fichier de clés qui était disponible dans mon chemin de classe lors de l'exécution de Spring n'était pas exactement le même que celui que j'avais dans mon répertoire "src/main/resources" et qui a provoqué l'exception Invalid Keystore Format. Lorsque j’ai testé avec keytool, j’utilisais celui du dossier "resources", ce qui induisait en erreur. 

Résolution du problème: dans votre fichier pom.xml, définissez la valeur de "filtrage" sur "false" . Un autre moyen de résoudre le problème consiste à spécifier explicitement l'emplacement du fichier de clés dans le fichier application.properties. Donc au lieu de:

server.ssl.key-store: classpath:keystore.jks

J'ai utilisé

server.ssl.key-store: keystore/keystore.jks
5
acaruci

J'ai rencontré le même problème lorsque load keystore avec le code suivant:

KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
Resource resource = new ClassPathResource(file);
trustStore.load(resource.getInputStream(), password.toCharArray());

Il s’est avéré que c’était le problème JDK, cela ne fonctionne pas avec jre1.8.0_25. lorsque je mets à niveau la version JDK vers le dernier jre1.8.0_121, cela fonctionne.

3
Dave Pateral

Je voyais cette exception:

Format de fichier de clés non valide

lors de l'exécution d'une application Java utilisant JRE-1.8.0_40 sous Linux CentOS 6.6 64 bits.

Avec JRE-1.8.0_172, l'exception est partie.

0
user674669