Java Netty SSL:如何编写信任管理器
我已经阅读了很多关于设置SSL客户机/服务器系统(无HTTP)的资料 我从和中获得灵感。 已经用命令创建了我的cert.jks文件Java Netty SSL:如何编写信任管理器,java,ssl,netty,Java,Ssl,Netty,我已经阅读了很多关于设置SSL客户机/服务器系统(无HTTP)的资料 我从和中获得灵感。 已经用命令创建了我的cert.jks文件 keytool -genkey -alias app-keysize 2048 -validity 36500 -keyalg RSA -dname "CN=app" -keypass mysecret-storepass mysecret -keystore cert.jks 在安全聊天示例中,有以下类别: public class SecureChatTrus
keytool -genkey -alias app-keysize 2048 -validity 36500
-keyalg RSA -dname "CN=app"
-keypass mysecret-storepass mysecret
-keystore cert.jks
在安全聊天示例中,有以下类别:
public class SecureChatTrustManagerFactory extends TrustManagerFactorySpi {
private static final TrustManager DUMMY_TRUST_MANAGER = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(
X509Certificate[] chain, String authType) throws CertificateException {
// Always trust - it is an example.
// You should do something in the real world.
// You will reach here only if you enabled client certificate auth,
// as described in SecureChatSslContextFactory.
System.err.println(
"UNKNOWN CLIENT CERTIFICATE: " + chain[0].getSubjectDN());
}
@Override
public void checkServerTrusted(
X509Certificate[] chain, String authType) throws CertificateException {
// Always trust - it is an example.
// You should do something in the real world.
System.err.println(
"UNKNOWN SERVER CERTIFICATE: " + chain[0].getSubjectDN());
}
};
public static TrustManager[] getTrustManagers() {
return new TrustManager[] { DUMMY_TRUST_MANAGER };
}
@Override
protected TrustManager[] engineGetTrustManagers() {
return getTrustManagers();
}
@Override
protected void engineInit(KeyStore keystore) throws KeyStoreException {
// Unused
}
@Override
protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
throws InvalidAlgorithmParameterException {
// Unused
}
}
如何正确地实现这个类
在此代码中(在SecureChatSslContextFactory类中):
为什么他们将null
而不是tmf.getTrustManagers()
放在serverContext.init(kmf.getKeyManagers(),null,null)行中代码>
如何正确地实现这个类
您需要定义一种方法来检查您是否以某种方式信任链[0]
上的证书。如果没有,则抛出一个certificateeexception
。(此处,SecureChatTrustManagerFactory
从不抛出任何东西,因此它绕过了验证,这会使连接对MITM攻击开放。)
如果您想半手动地进行此验证,您可以使用,即使是在相对简单的用例上
一般来说,正确的做法是不实施自己的。将其留给TrustManagerFactory
(或多或少采用与KeyManagerFactory
相同的方式)。顺便说一下,在这两种情况下,我建议对算法的值使用键/TrustManagerFactory.getDefaultAlgorithm()
,除非您有充分的理由不这样做。它至少是一个比SunX509
更好的默认值,我在很多情况下都看到了硬编码(实际上它不是默认的TMF算法值)
您可以从自己的信任库(例如,您可以专门为此连接加载的KeyStore
实例)初始化TMF
为什么他们要将null而不是tmf.getTrustManager()放在行中
serverContext.init(kmf.getKeyManager(),null,null)
信任管理器的null
和SecureRandom的null
返回默认值。这将是使用默认TMF算法(通常为PKIX
)初始化的默认信任管理器,使用默认信任存储(使用javax.net.ssl.trustStore
中的位置,或返回到jssecacerts
文件或cacerts
)。更多详细信息,请参见。仍无法使某些功能正常工作。。。我不知道如何实现我自己的TrustManagerFactory不要实现你自己的TMF,使用现有的。对不起,我的意思是我不能实现我自己的SecureChatSslContextFactory
SSLContext serverContext = null;
SSLContext clientContext = null;
try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(SecureChatKeyStore.asInputStream(),
SecureChatKeyStore.getKeyStorePassword());
// Set up key manager factory to use our key store
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
kmf.init(ks, SecureChatKeyStore.getCertificatePassword());
// Initialize the SSLContext to work with our key managers.
serverContext = SSLContext.getInstance(PROTOCOL);
serverContext.init(kmf.getKeyManagers(), null, null);
} catch (Exception e) {
throw new Error(
"Failed to initialize the server-side SSLContext", e);
}
try {
clientContext = SSLContext.getInstance(PROTOCOL);
clientContext.init(null, SecureChatTrustManagerFactory.getTrustManagers(), null);
} catch (Exception e) {
throw new Error(
"Failed to initialize the client-side SSLContext", e);
}