本文介绍了SSLSocket和AES加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We need to use AES encryption for client server communication, so when I enable the Cipher Suite TLS_DHE_RSA_WITH_AES_128_CBC_SHA on a SSLServetSocket ( using Java 6) and run the program, i am getting below exception

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

我的问题是我们可以通过SSLSocket进行AES加密吗或者它必须是常规套接字。如果我们不能使用它,谁能提供一个使用AES加密的客户端服务器通信示例。

My question is can we AES encryption over SSLSocket or it needs to be a regular socket. If we can't use it, can anyone please provide me an example of client server communication using AES encryption.

这里是代码

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);
        }
    }
}

在此感谢

推荐答案

匿名密码套件不执行任何身份验证。即使进行了加密,您仍在通过加密通道与远程方通话,但您不确定是谁,因此可能是中间人(MITM)。 对匿名密码套件的说明如下:

The anonymous cipher suites don't perform any authentication. Even with encryption, you're talking over an encrypted channel to a remote party, but you can't be sure who that is, so it could be a man in the middle (MITM). The TLS 1.1 specification says the following about anonymous cipher suites:



In short, don't use them (except for testing perhaps), or if you're really sure that there won't be an active MITM. (The TLS 1.2 specification is even more strongly worded against their usage.)

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

If you want to use TLS securely, you'll need a way for the client to verify the identity's remote party. In the vast majority of cases, this is done using an X.509 certificate. In particular, for the TLS_DHE_RSA_WITH_AES_128_CBC_SHA cipher suite, you'll need requires a certificate with an RSA public key (which explains the error message you get).

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

You should generate or request a certificate (self-signed or via a CA, perhaps your own, depending on how the clients can be configured) that identifies correctly the server. Not only the certificate will need to be trusted by the client (either explicitly or via an established CA), but its identity information will need to match the server's, under the name the client is trying to connect to it.

在您的示例中,尚不清楚您是在实现HTTPS(例如)还是基于SSL / TLS的自己的协议。 是该领域的最新规范,该规范统一了多种协议(例如HTTPS, LDAPS,IMAPS等)。由于它是最新的RFC,因此很少有库明确实现它(尽管它们可以在实践中实现,因为它合并了最佳实践)。毫无疑问,通常明智的做法是遵守(关于此主题的HTTP over TLS)指南:

From your example, it's not clear whether you're implementing HTTPS (for example) or your own protocol over SSL/TLS. RFC 6125 is the latest specification in this area, which unifies practices around multiple protocols (e.g. HTTPS, LDAPS, IMAPS, ...). Since it's quite a recent RFC, few libraries explicitly implement it (although they may do in practice, since it consolidates best practices). In doubt, it's usually sensible to adhere to the RFC 2818, section 3.1 (HTTP over TLS) guidelines on this subject:

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

Matching is performed using the matching rules specified by [RFC2459]. If more than one identity of a given type is present in the certificate (e.g., more than one dNSName name, a match in any one of the set is considered acceptable.) Names may contain the wildcard character * which is considered to match any single domain name component or component fragment. E.g., .a.com matches foo.a.com but not bar.foo.a.com. f.com matches foo.com but not bar.com.

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

,并且必须与URI中的IP完全匹配。

In some cases, the URI is specified as an IP address rather than a hostname. In this case, the iPAddress subjectAltName must be present
in the certificate and must exactly match the IP in the URI.

(。)

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

For practical reasons, IP addresses in certificates are not ideal (I don't think many commercial CAs would generate such certificates anyway). If you can, use the Subject Alternative Name extension, failing that, putting the host name in the CN= RDN of your Subject DN should be sufficient. There are notes on how to generate a CSR/certificate with a SAN in this answer. In particular, it's possible using the -ext option of Java 7's keytool (e.g. -ext san=dns:www.example.com); note that the keystore generated by Java 7's keytool should be usable on previous versions of the JRE too.

此外,如果除<$之外没有其他代码, c $ c> SSLContext.getDefault()(在这种情况下,您也可以使用默认的 SSLServerSocketFactory ),您需要指定密钥库:JRE对此没有默认值(与信任库相反)。可以使用 javax.net.ssl.keyStore (和相关的系统属性)来完成。在此答案中,例如,有关此主题的更多信息: https://stackoverflow.com/a/6341566/372643

In addition, if you don't have any other code than SSLContext.getDefault() (you could also use the default SSLServerSocketFactory in this case), you'll need to specify the keystore: the JRE doesn't have a default value for this (as opposed to the trust store). This can be done using the javax.net.ssl.keyStore (and related system properties). There is more on this topic in this answer (for example): https://stackoverflow.com/a/6341566/372643

这篇关于SSLSocket和AES加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 21:07