Я пытаюсь защитить систему приложений, которые должны быть подключены к нескольким машинам.Когда я начал переключаться с простых сокетов на SSLSockets, я начал получать две ошибки:
на стороне клиента:
"javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: сбой построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации к запрошенной цели "
На стороне сервера:
"javax.net.ssl.SSLHandshakeException: получено фатальное оповещение: certificate_unknown"
Я сократил код до только сокетов и поместил их в одну программу:
package sslTest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class TestMain {
public class TestModuleReceive {
int port = 4445;
SSLServerSocket ss;
SSLSocket socket;
TestModuleReceive() {
initServerSocket();
receiveConnection();
}
private void initServerSocket() {
try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/home/uName/.keystore"), ("password").toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ("password").toCharArray());
SSLContext sslcontext = SSLContext.getInstance("SSLv3");
sslcontext.init(kmf.getKeyManagers(), null, null);
ServerSocketFactory ssf =
sslcontext.getServerSocketFactory();
ss = (SSLServerSocket)
ssf.createServerSocket();
ss.setReceiveBufferSize(8200);
ss.bind(new InetSocketAddress(port));
}
catch (KeyStoreException e) { e.printStackTrace(); }
catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
catch (CertificateException e) { e.printStackTrace(); }
catch (FileNotFoundException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
catch (UnrecoverableKeyException e) { e.printStackTrace(); }
catch (KeyManagementException e) { e.printStackTrace(); }
}
public void receiveConnection() {
new Thread() { public void run() {
try {
socket = (SSLSocket) ss.accept();
receiveData();
}
catch (IOException e) { e.printStackTrace(); }
}}.start();
}
public void receiveData() {
try {
System.out.println(socket.getInputStream().read());
}
catch (IOException e) { e.printStackTrace(); }
}
}
public class TestModuleSend {
int port = 4445;
String address = "localhost";
SSLSocketFactory factory;
SSLSocket socket;
TestModuleSend() {
initFactory();
addConnection();
sendData();
}
private void initFactory() {
try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/home/uName/.keystore"), ("password").toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ("password").toCharArray());
SSLContext sslcontext = SSLContext.getInstance("SSLv3");
sslcontext.init(kmf.getKeyManagers(), null, null);
factory = sslcontext.getSocketFactory();
}
catch (KeyStoreException e) { e.printStackTrace(); }
catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
catch (CertificateException e) { e.printStackTrace(); }
catch (FileNotFoundException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
catch (UnrecoverableKeyException e) { e.printStackTrace(); }
catch (KeyManagementException e) { e.printStackTrace(); }
}
public void addConnection() {
// Initialize socket
try {
socket = (SSLSocket) factory.createSocket(InetAddress.getByName(address), port);
}
catch (UnknownHostException e1) { e1.printStackTrace(); }
catch (IOException e1) { e1.printStackTrace(); }
}
public void sendData() {
// Send single byte
try {
socket.getOutputStream().write((byte)0x00);
}
catch (IOException e) { e.printStackTrace(); }
}
}
TestMain() {
TestModuleReceive receive = new TestModuleReceive();
TestModuleSend send = new TestModuleSend();
}
public static void main(String[] args) {
TestMain testMain = new TestMain();
}
}
Когда я запускаю этот код, я получаю следующую трассировку стека:
javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1731)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:974)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1158)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:773)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:94)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:69)
at sslTest.TestMain$TestModuleReceive.receiveData(TestMain.java:71)
at sslTest.TestMain$TestModuleReceive$1.run(TestMain.java:63)
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1665)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:258)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:252)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1165)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:610)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:546)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:913)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1158)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:652)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:78)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:92)
at sslTest.TestMain$TestModuleSend.sendData(TestMain.java:121)
at sslTest.TestMain$TestModuleSend.<init>(TestMain.java:87)
at sslTest.TestMain.<init>(TestMain.java:129)
at sslTest.TestMain.main(TestMain.java:133)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:324)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:224)
at sun.security.validator.Validator.validate(Validator.java:235)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1144)
... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:197)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:319)
... 18 more
Может кто-нибудь сказать мне, что я делаю неправильно?
Спасибо.