sockets - 如果套接字握手中的客户端证书中有两个有效证书,则在 SSL 连接中使用哪个证书
问题描述
我的密钥库中已经有一个有效的证书,并且与服务器的握手过程正在运行。当在同一个密钥库中添加另一个具有不同 CN 的证书并与服务器连接时,从服务器获取错误“访问被拒绝,无效端点”。我认为在与服务器连接时,当有两个有效的证书用于客户端证书使用(现有的证书和新导入的证书)时,第二个证书用于 ssl 连接。我想知道的是,如果密钥库中的有效证书多于一个,则使用哪一个。它与证书别名有关吗?以下是套接字连接的代码片段。
try {
SSLSocketFactory factory = null;
try {
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "*****".toCharArray();
ctx = SSLContext.getInstance("TLSv1.2");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("testkeys"), passphrase);
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), null, null);
factory = ctx.getSocketFactory();
} catch (Exception e) {
throw new IOException(e.getMessage());
}
SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
String[] cipherSuites = socket.getSupportedCipherSuites();
socket.setEnabledCipherSuites( cipherSuites );
socket.setNeedClientAuth(false);
socket.startHandshake();
解决方案
类似当有很多时,使用来自 keystore 和 truststore 的哪个密钥和证书?为服务器。
对于 SunX509 KeyManagerFactory:
在初始化时,它创建一个 HashMap,其中包含来自密钥库的所有私钥条目,由别名键控;
握手调用
chooseClientAlias
,对于服务器指定/请求的每个 <=1.2 certificate_type 或 1.3 sigalg(在代码中称为 keyType)按HashIterator
顺序检查每个 HashMap 条目(由从别名的哈希码)查看叶子证书是否具有该密钥类型,并且链中的任何证书都由服务器指定的 CA 之一颁发,除非服务器将 CA 列表留空,在这种情况下,这部分检查将被跳过.
如果您选择了错误的证书和密钥,请检查服务器是否在其 CertificateRequest 消息中指定了正确的 CA 列表。您可以通过运行 sysprop 在 Java 客户端执行此操作javax.net.debug=ssl:handshake
,或者在 1.3 中使用网络级工具(如 wireshark 或 tcpdump)除外。
推荐阅读
- javascript - 二叉树的最低共同祖先:有人知道为什么我的输出未定义吗?
- python - 如何在 Pandas 中将所有列堆叠/附加到一列中?
- c - 关于C中的结构,如何将数据从结构复制到字符串数组
- oracle-apex - 编辑 Oracle Apex“选择列表”页面项目时如何首先显示所选项目
- css - 如何在单击时使用 css 旋转插入符号
- python - 如何使生成器在创建时而不是在迭代期间抛出
- javascript - 如何在 Javascript 中读取本地文件(从 Electron 应用程序运行)
- c# - 如何隐藏外壳中某些页面的后退按钮?
- typescript - 如果选项中包含字符串,则打字稿
- reactjs - 我如何才能完全匹配深度嵌套在反应路由器 6 中的路由?