与浏览器和我的java服务器建立客户端/服务器SSL连接?

时间:2011-11-13 05:45:40

标签: java sockets ssl

我正在尝试创建一个HttpsServer / Client,以便我可以创建一个代理来检查从浏览器到服务器的流量。这些类型的工具对于测试Web应用程序安全性的人来说非常宝贵。我决定使用httpclient为我的服务器发送请求和httpcore组件。目前我只是试图在端口8080上建立浏览器和服务器之间的ssl套接字连接。我已经阅读了所有内容,但似乎仍然无法使其工作。以下是我到目前为止所做的步骤:

  1. 使用keytool创建了CA证书并将其添加到名为cacerts的文件中

  2. 我将此证书添加到侦听端口8080

  3. 的firefox浏览器实例中
  4. 在我的代码中,我执行以下操作以在服务器代码中调用该证书

        KeyStore ks = KeyStore.getInstance("JKS");  
        ks.load(new FileInputStream("C:\\Program Files\\Java\\jre6\\bin\\cacerts"), "password".toCharArray());
    
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, "password".toCharArray());
    
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(kmf.getKeyManagers(), null, null);
    
    
        ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
        serversocket = ssocketFactory.createServerSocket(port);
    
  5. 然后,当我在套接字上调用accept时,如下所示,我得到以下异常:

    I/O error initialising connection thread: No available certificate or key corresponds    to the SSL cipher suites which are enabled.
     javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL     cipher suites which are enabled.
     at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.checkEnabledSuites(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.accept(Unknown Source)
    at DefaultHttpServer$RequestListenerThread.run(DefaultHttpServer.java:151) 
    

    以下是抛出异常的行:

       Socket socket = serversocket.accept(); 
    

    关于我在这里做错了什么的想法?只是尝试与端口8080建立ssl套接字连接,浏览器正在发送请求。

    更新11/13

    到目前为止,我已经获取了一些信息,然后创建了一个单独的密钥库文件。这就是我所做的

    C:\Users\Steve>keytool -genkey -alias serverprivkey -keystore privateKey.store
    

    然后我将此文件privateKey.store从我的用户目录复制到我的项目文件夹,并在我的代码中进行了以下更改:

            KeyStore ks = KeyStore.getInstance("JKS");  
            ks.load(new FileInputStream("privateKey.store"), "pass123".toCharArray());
    
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, "pass123".toCharArray());
    

    我知道它正确抓取该文件,因为如果密码错误,我会得到例外。但是,我仍然得到同样的例外。任何想法接下来要尝试什么?

    以下是privateKey.store中的内容:

     C:\Users\Steve>keytool -list -v -keystore privateKey.store
    Enter keystore password:
    
    Keystore type: JKS
     Keystore provider: SUN
    
    Your keystore contains 1 entry
    
    Alias name: serverprivkey
    Creation date: Nov 13, 2011
    Entry type: PrivateKeyEntry
    Certificate chain length: 1
    Certificate[1]:
    Owner: CN=sven rbera, OU=application developement, O=whs, L=san hjose, ST=
     ca, C=ca
     Issuer: CN=sven rbera, OU=application developement, O=whs, L=san hjose, ST
     =ca, C=ca
     Serial number: 4ec00a18
     Valid from: Sun Nov 13 10:19:04 PST 2011 until: Sat Feb 11 10:19:04 PST 2012
     Certificate fingerprints:
         MD5:  9C:A7:2B:CE:DC:AD:5B:9C:D6:B7:71:6C:EC:91:8A:24
         SHA1: 47:8F:9B:A2:E1:31:A5:D9:F6:71:8A:CA:3F:CB:BA:FC:C7:2D:F5:A8
         Signature algorithm name: SHA1withDSA
         Version: 3
    


    我已将我的密钥更改为现在使用RSA。此外,我添加了SSL的调试标志并使其可用。完全理解它有点棘手,但看起来它找到关键serverprivkey2就好了。然后它进入trustStore,我在该列表中看不到任何看起来像是来自我的东西。我真的不知道我应该期待在那一节看到什么。有什么想法吗?

                ***
                found key for : serverprivkey2
                chain [0] = [
                [
                  Version: V3
                  Subject: CN=steve, OU=labarbera, O=whs, L=sj, ST=ca, C=ca
                  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
    
                  Key:  Sun RSA public key, 1024 bits
                  modulus: 140985119594686674696976228136679950023710897166974487014150510574037897724033913877362573524361519470364814271848450916151017718803985253447854099124509296799994400199293690731598145912452994962103007955337967369473821653235218532303270695076070736956288068926075705380732910518314547899958542901647381772169
                  public exponent: 65537
                  Validity: [From: Sun Nov 13 14:45:44 PST 2011,
                               To: Sat Feb 11 14:45:44 PST 2012]
                  Issuer: CN=steve, OU=labarbera, O=whs, L=sj, ST=ca, C=ca
                  SerialNumber: [    4ec04898]
    
                ]
                  Algorithm: [SHA1withRSA]
                  Signature:
                0000: C8 81 37 74 E9 7C A4 76   9F FD EC 8A 78 69 F2 A4  ..7t...v....xi..
                0010: 64 1E C9 98 FD 99 FB 48   3D E2 C5 C5 EB A3 34 1B  d......H=.....4.
                0020: 7C BE B3 E4 F7 4D 90 F1   AB A6 4D 36 97 95 9B 95  .....M....M6....
                0030: 90 C1 B9 28 9C DE A0 4A   AD C7 10 8F 06 57 A6 2B  ...(...J.....W.+
                0040: 51 45 63 73 ED 1E AF 5F   61 E2 87 1A 7C CD 4E 3F  QEcs..._a.....N?
                0050: A7 18 15 FA 73 94 58 46   62 46 42 F9 31 12 2F C7  ....s.XFbFB.1./.
                0060: 6E 6E A0 3F 17 FA A8 24   FC 68 83 88 E2 23 EF DE  nn.?...$.h...#..
                0070: E9 F5 58 AB 16 19 1B 82   72 C6 A0 A7 7E 41 36 1C  ..X.....r....A6.
    
                ]
                ***
    
    trustStore is: C:\Program Files\Java\jre6\lib\security\cacerts
    trustStore type is : jks
    trustStore provider is : 
    init truststore
    adding as trusted cert:
    ... bunch certs none of which look familiar?
    

3 个答案:

答案 0 :(得分:1)

  

1.使用keytool处理CA证书并将其添加到名为cacerts的文件

我无法理解你在这里做了什么 您是否创建了公钥/私钥对并将其存储到cacerts密钥库? 你不应该这样做。
 cacerts旨在用作信任库,而不是用作密钥库。

您应该已经创建了一个新的密钥库并加载了该密钥库以供KeyManager使用。

例外情况不明确 它无法在cacerts中找到私钥,这可能与您选择的别名有关,或者证书没有适当的扩展用于加密。
我认为别名问题最有可能。

我记得不试图调试这个。
而是为您的服务器创建一个单独的密钥库,然后加载它 不要使用cacert

更新:确保使用RSA作为keytool命令中的密钥算法

答案 1 :(得分:0)

史蒂夫,如果你只是需要检查交通,你不必重新发明轮子。使用Paros等已有的代理服务器之一来观看流量。

答案 2 :(得分:0)

我通常希望在“C:\ Program Files \ Java \ jre6 \ lib \ security”下找到cacerts。您的程序正在“C:\ Program Files \ Java \ jre6 \ bin”中查找它。