我正在开发一个项目,想要添加SSL,因此我创建了一个简单的客户/服务器测试实现来检查它是否有效,但是出现了NoSuchAlgorithmException异常。以下是我抛出异常的服务器代码:
import java.io.*;
import java.net.*;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.*;
public class SslServer
{
private static final int PORT = 5555;
public static void main(String[] args)
{
SecureRandom sr = new SecureRandom();
sr.nextInt();
try {
//client.public is the keystore file that holds the client's public key (created with keytool)
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(new FileInputStream("client.public"), "clientpublicpw".toCharArray());
//server.private is the key pair for the server (created with keytool)
KeyStore serverKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(new FileInputStream("server.private"), "serverprivatepw".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(clientKeyStore);
//This next line is where the exception occurs
KeyManagerFactory kmf = KeyManagerFactory.getInstance("TLS");
kmf.init(serverKeyStore, "serverprivatepw".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), sr);
SSLServerSocketFactory sf = sslContext.getServerSocketFactory();
SSLServerSocket ss = (SSLServerSocket)sf.createServerSocket(SslServer.PORT);
ss.setNeedClientAuth(true);
BufferedReader in = new BufferedReader(new InputStreamReader(ss.accept().getInputStream()));
String line = null;
while((line = in.readLine()) != null)
{
System.out.println(line);
}
in.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
我得到的堆栈跟踪如下:
java.security.NoSuchAlgorithmException: TLS KeyManagerFactory not available
at sun.security.jca.GetInstance.getInstance(Unknown Source)
at javax.net.ssl.KeyManagerFactory.getInstance(Unknown Source)
at SslServer.main(SslServer.java:32)
我尝试将“TLS”替换为“SSL”,但我仍然得到了相同的异常。这对我来说没有意义。TLS和SSL怎么可能不被支持呢?这是我第一次尝试实现SSL,似乎很难找到好的资源,其中包括良好解释的代码示例。有人能告诉我为什么会出现这种异常或指出我的代码有什么问题吗?
char[]
或密码回调来处理密码,在真正的应用中永远不要硬编码你的密码(参见https://dev59.com/rGox5IYBdhLWcg3w74q2#8889285)。 - BrunoreadLine
返回null
并不是停止读取(从任何类型的套接字)的好方法,请参见此处的讨论:https://dev59.com/1VjUa4cB1Zd3GeqPRneb#6425509 - BrunoSunX509
,而不是TLS
。它还使用了一个相当旧的Java版本,TMF的新默认值是PKIX
。(我仍然不确定本文中密钥库文件命名约定的正确性。) - Bruno