Java - 没有共同的密码套件

时间:2017-09-05 15:34:26

标签: java ssl server

我正在创建一个SSL服务器并尝试向其发送数据,但是当我创建它时,它会出现以下错误:javax.net.ssl.SSLHandshakeException: no cipher suites in common 这是我的完整代码:

    Logger.ready("log.txt");
    Logger.log("Logger is now ready!");
    System.setProperty("javax.net.ssl.trustStore", "MyKeytool.keytool");
    System.setProperty("javax.net.ssl.keyStorePassword", "MyPassword");
    Logger.log("Properties are set!");
    try {
        SSLServerSocket server = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(9999);
        server.setEnabledCipherSuites(new String[] {"TLS_RSA_WITH_AES_128_CBC_SHA"});
        Logger.log("Sever was created & is read to connect!");
        while (true) {
            new ServerThread(server.accept()).start();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

并且客户端支持它会出现以下错误:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

所以我的问题是:

Q1:这是完全错误的方式吗?如果这是多么糟糕的话呢?

Q2:我当前正在存储我的keytool(客户端,keytool是由java keygen生成的keytool文件)没有保存(与aot编译的jar在同一目录中),但这是保存还是Crackers可以做任何事情这个keytool喜欢从连接或类似的东西读取什么?

问题3:我应该如何解决我的问题(建立正确的连接),以便我可以发送数据?

1 个答案:

答案 0 :(得分:0)

好消息是您的代码与SSL服务器连接,并尝试SSL握手。

SSL握手中发生的第一件事是,双方试图就双方都可接受的密码套件达成一致。密码套件是认证,加密,消息认证和密钥交换算法的命名组合。

通常,服务器有一个它理解并认为可接受安全的密码套件列表,而客户端有另一个列表。

例如,配置为仅支持TLS1及更高版本的OpenSSL服务器可能具有此密码套件列表:

ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
SRP-DSS-AES-256-CBC-SHA SSLv3 Kx=SRP      Au=DSS  Enc=AES(256)  Mac=SHA1
SRP-RSA-AES-256-CBC-SHA SSLv3 Kx=SRP      Au=RSA  Enc=AES(256)  Mac=SHA1
SRP-AES-256-CBC-SHA     SSLv3 Kx=SRP      Au=SRP  Enc=AES(256)  Mac=SHA1
DHE-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=DSS  Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA256
DHE-DSS-AES256-SHA256   TLSv1.2 Kx=DH       Au=DSS  Enc=AES(256)  Mac=SHA256
DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
DHE-DSS-AES256-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(256)  Mac=SHA1
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA1
DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH       Au=DSS  Enc=Camellia(256) Mac=SHA1
ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
ECDH-RSA-AES256-SHA384  TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256)  Mac=SHA384
ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256)  Mac=SHA384
ECDH-RSA-AES256-SHA     SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256)  Mac=SHA1
ECDH-ECDSA-AES256-SHA   SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256)  Mac=SHA1
AES256-GCM-SHA384       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(256) Mac=AEAD
AES256-SHA256           TLSv1.2 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA256
AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1

...等(我的系统共有80个)

客户端告诉服务器它支持哪些服务器。服务器在其支持的密码套件列表中选择一个,并响应告诉客户端使用哪个密码套件。

您已选择仅使用一个密码套件列表来配置客户端。似乎服务器不支持TLS_RSA_WITH_AES_128_CBC_SHA,因此服务器响应了握手失败,包括一条有用的消息:no cipher suites in common

仅指定一个密码套件并不是一个好主意,因为您允许的密码越少,它在服务器列表中的可能性就越小。

除非您有充分的理由指定密码套件,否则您应该让客户端使用默认列表。

getSupportedCipherSuites()将为您提供Java可以支持的所有密码套件 - 不启用所有这些密码套件,因为有很多功能在默认情况下被禁用。

在您设置任何内容之前调用的

getEnabledCipherSuites()将为您提供默认值。如果默认值不符合您的需求,您可以从这些默认值开始,并根据需要添加/删除。

包含私钥的文件与任何其他文件一样安全 - 它不会通过SSLServerSocket泄露。您应该考虑其他可能被阅读的方式 - 确保它被读取保护,等等。考虑将其加密,然后考虑如何保护密码。在便利性,成本和安全性之间选择了一个平衡点。有些系统需要人员在每次系统启动时输入密钥文件密码。其他系统接受风险,并拥有密码文件或未加密的密钥文件(信任操作系统文件权限,物理和网络安全性)。