SSLSocket和AES加密

时间:2012-01-27 00:22:49

标签: ssl aes

我们需要使用AES加密进行客户端服务器通信,因此当我在SSLServetSocket上启用Cipher Suite TLS_DHE_RSA_WITH_AES_128_CBC_SHA(使用Java 6)并运行该程序时,我会遇到异常

没有可用的证书或密钥对应启用的SSL密码套件

我的问题是我们可以通过SSLSocket进行AES加密,还是需要常规套接字。如果我们不能使用它,任何人都可以请给我一个使用AES加密的客户端服务器通信的例子。

这是代码

public class AESServerSocketTest {

    public static void main(String[] args) {
        SSLServerSocket serverSocket;
        try 
        {
            SSLContext ctx = javax.net.ssl.SSLContext.getDefault();
            serverSocket =(SSLServerSocket)ctx.getServerSocketFactory().createServerSocket(8181);
            serverSocket.setEnabledCipherSuites(new String[]{"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"});        

            SSLSocket in = (SSLSocket)serverSocket.accept(); 
        }
        catch (Exception e) 
        {
            System.out.println("Exception " + e);
        }
    }
}

先谢谢

2 个答案:

答案 0 :(得分:1)

匿名密码套件不执行任何身份验证。即使使用加密技术,您也可以通过加密频道与远程方通话,但您无法确定是谁,因此它可能是中间人(MITM)。 TLS 1.1 specification对匿名密码套件说了以下内容:

  

以下密码套件用于完全匿名   Diffie-Hellman通信,其中任何一方都未通过身份验证。   请注意,此模式容易受到中间人攻击,并且是   因此弃用。

简而言之,不要使用它们(除了测试之外),或者如果你真的确定不会有活跃的MITM。 (TLS 1.2规范的用法更加强烈。)

如果您想安全地使用TLS,您需要一种方法让客户验证身份的远程方。在绝大多数情况下,这是使用X.509证书完成的。特别是,对于TLS_DHE_RSA_WITH_AES_128_CBC_SHA密码套件,您需要一个带有RSA公钥的证书(这解释了您收到的错误消息)。

您应该生成或请求证书(自签名或通过CA,可能是您自己的,具体取决于客户端的配置方式),以正确识别服务器。客户端不仅需要信任证书(显式或通过已建立的CA),而且其身份信息需要与客户端尝试连接的服务器名称相匹配。

从您的示例中,您不清楚是通过SSL / TLS实施HTTPS(例如)还是您自己的协议。 RFC 6125是此领域的最新规范,它统一了多种协议(例如HTTPS,LDAPS,IMAPS等)的实践。由于它是最近的RFC,很少有库明确地实现它(尽管它们可能在实践中实现,因为它整合了最佳实践)。有疑问,遵守RFC 2818, section 3.1(HTTP over TLS)关于此主题的指南通常是明智的:

  

如果存在类型为dNSName的subjectAltName扩展名,则必须   用作身份。否则,(最具体的)通用名称
  必须使用证书的Subject字段中的字段。虽然   使用Common Name是现有的做法,它已被弃用   鼓励证书颁发机构改为使用dNSName。

     

使用指定的匹配规则执行匹配   [RFC2459]。如果存在多个给定类型的标识   证书(例如,多个dNSName名称,任何一个匹配   该集合被认为是可接受的。)名称可能包含通配符   字符*,被认为匹配任何单个域名   组件或组件片段。例如, .a.com匹配foo.a.com但是   不是bar.foo.a.com。 f .com匹配foo.com但不匹配bar.com。

     

在某些情况下,URI被指定为IP地址而不是a   主机名。在这种情况下,iPAddress subjectAltName必须存在   在证书中,必须与URI中的IP完全匹配。

RFC 6125 explicitly discourages the use of wildcard certificates。)

由于实际原因,证书中的IP地址并不理想(我认为很多商业CA都不会生成此类证书)。如果可以,请使用主题备用名称扩展名,如果不这样做,将主机名放在主题DN的CN= RDN中就足够了。有关如何在this answer中使用SAN生成CSR /证书的说明。特别是,可以使用-ext option of Java 7's keytool(例如-ext san=dns:www.example.com);请注意,Java 7的keytool生成的密钥库也应该可以在以前版本的JRE上使用。

此外,如果您没有除SSLContext.getDefault()以外的任何其他代码(在这种情况下您也可以使用默认的SSLServerSocketFactory),则需要指定密钥库:JRE不会没有默认值(与信任存储相对)。这可以使用javax.net.ssl.keyStore(以及相关的系统属性)来完成。此答案中有更多内容(例如):https://stackoverflow.com/a/6341566/372643

答案 1 :(得分:0)

  

没有可用的证书或密钥对应于SSL密码套件   已启用

此错误表示:

您启用的密码套件不适合/接受私钥/证书(这很可能意味着例如短密钥长度)或您尚未配置任何证书。