gpt4 book ai didi

java - 客户端/服务器程序在初始化 KeyManagerFactoryImpl 时出错

转载 作者:太空宇宙 更新时间:2023-11-03 13:35:47 25 4
gpt4 key购买 nike

我正在创建一个通过 Java SSL 套接字连接的客户端和服务器。仅对服务器进行身份验证(单向身份验证)。客户端连接到服务器后,客户端将提示用户输入一行并将其发送到服务器。

每当我运行客户端时,我都会收到以下错误:

Exception in thread "main" java.lang.IllegalStateException: KeyManagerFactoryImpl is not initialized
at sun.security.ssl.KeyManagerFactoryImpl.engineGetKeyManagers(KeyManagerFactoryImpl.java:51)
at javax.net.ssl.KeyManagerFactory.getKeyManagers(KeyManagerFactory.java:289)
at SSLClient.createSSLContext(SSLClient.java:43)
at SSLClient.main(SSLClient.java:50)

我的客户端代码是:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class SSLClient {

public static final int PORT_NO = 9020;
static void doProtocol( Socket cSock ) throws IOException
{
OutputStream out = cSock.getOutputStream();
InputStream in = cSock.getInputStream();

out.write("World".getBytes());
out.write('!');

int ch = 0;
while ((ch = in.read()) != '!')
{
System.out.print((char)ch);
}

System.out.println((char)ch);
}
static SSLContext createSSLContext() throws Exception
{
// set up a key manager for our local credentials
KeyManagerFactory mgrFact = KeyManagerFactory.getInstance("SunX509");
// KeyStore clientStore = KeyStore.getInstance("PKCS12");

// clientStore.load(new FileInputStream("client.p12"), "Password");

// mgrFact.init(clientStore, "password");

// create a context and set up a socket factory
SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(mgrFact.getKeyManagers(), null, null);

return sslContext;
}

public static void main( String[] args ) throws Exception
{
SSLContext sslContext = createSSLContext();
SSLSocketFactory fact = sslContext.getSocketFactory();
// SSLSocketFactory fact = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket cSock = (SSLSocket)fact.createSocket("localhost", PORT_NO);

doProtocol(cSock);
}
}

我的服务器代码是:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyStore;
import java.security.Principal;
import java.util.Date;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
import javax.security.auth.x500.X500Principal;

import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.crypto.tls.Certificate;
import org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory;


public class SSLSocketServer {

public static int SERVER_PORT = 9020;


static boolean isEndEntity( SSLSession session ) throws SSLPeerUnverifiedException
{
Principal id = session.getPeerPrincipal();
if (id instanceof X500Principal)
{
X500Principal x500 = (X500Principal)id;
String Expireddate = x500.getName("Expireddate");
String Name = x500.getName("Name");
return (Name.equals("James") && Date.parse(Expireddate) > System.currentTimeMillis());
}

return false;
}


/**
* Carry out the '!' protocol - server side.
*/
static void doProtocol(
Socket sSock)
throws IOException
{
System.out.println("session started.");

InputStream in = sSock.getInputStream();
OutputStream out = sSock.getOutputStream();
// Send Key

out.write("Hello ".getBytes());

int ch = 0;
while ((ch = in.read()) != '!')
{
out.write(ch);
}

out.write('!');

sSock.close();
}
/**
* Create an SSL context with identity and trust stores in place
*/
SSLContext createSSLContext()
throws Exception
{
// set up a key manager for our local credentials
KeyManagerFactory mgrFact = KeyManagerFactory.getInstance("SunX509");
KeyStore serverStore = KeyStore.getInstance("JKS");

serverStore.load(new FileInputStream("server.jks"), "password".toCharArray());

mgrFact.init(serverStore, "password".toCharArray());

// set up a trust manager so we can recognize the server
TrustManagerFactory trustFact = TrustManagerFactory.getInstance("SunX509");
KeyStore trustStore = KeyStore.getInstance("JKS");

trustStore.load(new FileInputStream("trustStore.jks"), "trustpassword".toCharArray());

trustFact.init(trustStore);

// create a context and set up a socket factory
SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(mgrFact.getKeyManagers(), trustFact.getTrustManagers(), null);

return sslContext;
}


public static void main( String[] args ) throws Exception
{
SSLServerSocketFactory fact = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket sSock = (SSLServerSocket)fact.createServerSocket(SERVER_PORT);

SSLSocket sslSock = (SSLSocket)sSock.accept();
sSock.setNeedClientAuth(false); // current ignore

doProtocol(sslSock);
}
}

最佳答案

您需要调用 KeyManagerFactories 初始化方法之一:

init(KeyStore ks, char[] password)

init(ManagerFactoryParameters spec)

在调用 KeyManagerFactory.getKeyManagers() 之前,否则它会抛出观察到的 IllegalStateException

例如,您的代码可能如下所示:

...
final KeyStore keyStore = KeyStore.getInstance("JKS");
try (final InputStream is = new FileInputStream(fullPathOfKeyStore())) {
keyStore.load(is, JKS_PASSWORD);
}
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
kmf.init(keyStore, KEY_PASSWORD);
...

参见 programcreek.com完整的例子。

关于java - 客户端/服务器程序在初始化 KeyManagerFactoryImpl 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40970405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com