Java程序的自签名证书

3
我有一个Java程序,该程序连接到一个服务器并与该服务器交互,并执行(打印“hello world”)简单的任务。
我的Java程序是用于与VMware ESXi服务器进行交互的,以下是代码:
ServiceInstance si = new ServiceInstance(new URL("https://10.100.13.36/sdk"), "root", "teamw0rk", true)
true参数表示忽略证书为真。
尽管这是与VMware进行的交互,但问题纯粹是证书问题。因为当我将忽略证书设置为false时,从库文件中得到了一般的证书期望。
程序如下所示。
package com.vmware.vim25.mo.samples;

import java.net.URL;
import com.vmware.vim25.*;
import com.vmware.vim25.mo.*;

public class HelloVM 
{
    public static void main(String[] args) throws Exception
    {
        long start = System.currentTimeMillis();
        ServiceInstance si = new ServiceInstance(new URL("https://10.100.13.36/sdk"), "root", "teamw0rk", false);
        long end = System.currentTimeMillis();
        System.out.println("time taken:" + (end-start));
        Folder rootFolder = si.getRootFolder();
        String name = rootFolder.getName();
        System.out.println("root:" + name);
        ManagedEntity[] mes = new InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine");
        if(mes==null || mes.length ==0)
        {
            return;
        }

        VirtualMachine vm = (VirtualMachine) mes[0]; 

        VirtualMachineConfigInfo vminfo = vm.getConfig();
        VirtualMachineCapability vmc = vm.getCapability();

        vm.getResourcePool();
        System.out.println("Hello " + vm.getName());
        System.out.println("GuestOS: " + vminfo.getGuestFullName());
        System.out.println("Multiple snapshot supported: " + vmc.isMultipleSnapshotsSupported());

        si.getServerConnection().logout();
    }

}

这个错误与期望 SSL 证书有关。

Exception in thread "main" java.rmi.RemoteException: VI SDK invoke exception:javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address 10.100.13.36 found
    at com.vmware.vim25.ws.WSClient.invoke(WSClient.java:182)
    at com.vmware.vim25.ws.WSClient.invoke(WSClient.java:124)
    at com.vmware.vim25.ws.VimStub.retrieveServiceContent(VimStub.java:1521)
    at com.vmware.vim25.mo.ServiceInstance.<init>(ServiceInstance.java:85)
    at com.vmware.vim25.mo.ServiceInstance.<init>(ServiceInstance.java:69)
    at com.vmware.vim25.mo.samples.HelloVM.main(HelloVM.java:16)

我确认程序错误与VMware无关,而与证书有关。

第一步是使用以下命令创建JKS文件:

c:/java/jre/bin>keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048

它会在bin文件夹中创建keystore.jks。

我需要了解如何在Java程序中引用这个keystore.jks。(我对此知识较少...抱歉)

如何生成证书以及导入和导出证书的含义。

在我的情况下,我需要导入还是导出。

最初我向一个人提出了问题。

他回答说:“在高层次上,您需要将服务器证书放入您的密钥库中,并将密钥库包含在JVM参数中。”

请澄清我的疑惑并为此提供一些说明。

谢谢。

4个回答

1

您遇到的错误是因为URL中的主机名(10.100.13.36)与服务器SSL证书中包含的任何服务器名称不匹配。

CertificateException:未找到与IP地址10.100.13.36匹配的任何主题备用名称

请尝试使用URL请求中实际的服务器名称进行重试。您可能需要使用服务器的完全限定名称。因为您需要匹配服务器所使用的SSL证书中包含的服务器名称。

您可以使用curl命令查看服务器的证书,例如:

curl -v https://10.100.13.36/sdk

以下是微软的SSL证书包含的内容:

C:\>curl -v https://www.microsoft.com
* About to connect() to www.microsoft.com port 443 (#0)
*   Trying 64.4.11.20... connected
* Connected to www.microsoft.com (64.4.11.20) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: c:\tpf$\bin\curl-ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
*        subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; OU=MSCOM; CN=
www.microsoft.com
*        start date: 2012-03-29 19:29:53 GMT
*        expire date: 2014-03-29 19:29:53 GMT
*        common name: www.microsoft.com (matched)
*        issuer: DC=com; DC=microsoft; DC=corp; DC=redmond; CN=Microsoft Secure
Server Authority
*        SSL certificate verify ok.
> GET / HTTP/1.1

我尝试了你提到的方法。我的服务器名称是正确的。服务器名称是10.100.13.36,GET方法应该使用/sdk。 - Pratap M
当我运行keytool时,我输入的字符串被用作生成证书中的CN(通用名称)值。通常,CN值是Web服务器的主机名,这是正在验证的内容,并且预期是您在URL中放置的IP地址。 - HeatfanJohn
我刚刚发现Java 7中的keytool支持向证书添加主题备用名称。 添加选项为:-ext san = ip:10.100.13.36。有关更多信息,请参见http://docs.oracle.com/javase/7/docs/technotes/tools/windows/keytool.html。 - HeatfanJohn
有关证书验证,包括 IP 地址验证,请参阅 https://dev59.com/gGDVa4cB1Zd3GeqPaiul 了解更多信息。 - HeatfanJohn
我尝试找出服务器的subjectalt名称。它是DNSName=localhost.localdomain。 - Pratap M
显示剩余4条评论

0

简短回答:

首先,使用服务器的 DNS 名称进行测试,而不是 IP 地址(长说明在此处)。

其次,如果您想使用证书,则必须导入服务器证书,而不是自己生成证书...


服务器仅位于我的系统中。它是一个私有地址,由VMware充当其自己的服务器。 - Pratap M

0
证书由Tomcat使用,而不是您的客户端。请参阅Tomcat SSL文档。

我的真正问题是,当我运行应用程序时,它会说无法识别DNS名称,而且没有导入任何证书。我的程序如何解决服务器名称识别的问题...首先,在验证证书之前,我们的程序应该确定服务器名称是什么(使用https检查)...它无法识别DNS或IP地址...我如何确保使用keytool可以正确识别服务器名称(请记住,我只能使用keytool的导入形式...因为我在这里不生成证书...) - Pratap M

0

在生成证书时尝试添加-dname CN=10.100.13.36。我认为您甚至不需要使用主题备用名称。通用名称(CN)应该等于您在连接URL时使用的域名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接