Encryption 需要关于自签名SSL和Java的建议吗

Encryption 需要关于自签名SSL和Java的建议吗,encryption,ssl,self-signed,Encryption,Ssl,Self Signed,关于如何使用Java处理自签名证书的问题已经被问了很多次,并且经常提供实现。但是,我不确定这些实现是否会给我所寻求的安全性/信任 我的情况如下:我有一个客户端程序连接到我们的服务器应用程序。这两项我们都完全可以控制。我们的客户端使用https将一个流发布到服务器上的URL,服务器响应。目前(我正试图解决这个问题)服务器有一个自签名证书。Java不喜欢这一点,而且仅用于测试,我们几乎完全忽略了证书,因为我们信任任何证书 我对SSL知之甚少。我的老板说我们可以使用我们的自签名证书,只要我们不做密码,

关于如何使用Java处理自签名证书的问题已经被问了很多次,并且经常提供实现。但是,我不确定这些实现是否会给我所寻求的安全性/信任

我的情况如下:我有一个客户端程序连接到我们的服务器应用程序。这两项我们都完全可以控制。我们的客户端使用https将一个流发布到服务器上的URL,服务器响应。目前(我正试图解决这个问题)服务器有一个自签名证书。Java不喜欢这一点,而且仅用于测试,我们几乎完全忽略了证书,因为我们信任任何证书

我对SSL知之甚少。我的老板说我们可以使用我们的自签名证书,只要我们不做密码,它就会安全。关键公众人物。这听起来对我来说是正确的,但很多帖子都说自签名证书自动容易受到中间人攻击。这是否意味着SSL会发送密码。密钥和证书一起吗


既然我们对两端都有控制权,我们是否应该自己用一个密钥加密数据,然后在最后用密钥解密?还是有理由使用SSL?

反对自签名证书的论点主要适用于web应用程序。由于使用当前的基础结构,浏览器将无法验证您的自签名证书


由于您可以控制客户机,因此只需将所需的证书硬编码到客户机中即可。例如,您可以计算证书的sha1散列,并检查其是否与预期值匹配。这样,您甚至不需要信任数百个CA。

与其盲目信任任何证书(这会使连接容易受到MITM攻击),不如将Java客户端配置为信任该特定证书。自签名证书不会固有地使SSL/TLS连接容易受到MITM攻击,它们只是使其分发和信任评估更特定于此特定部署(即,您必须手动配置)

你至少可以通过3种方式来实现这一点(选择最简单的一种,我建议要点2):

  • 将服务器证书导入客户端的全局信任存储(JRE目录中的lib/security/cacerts)。这将使所有应用程序使用此JRE信任此证书运行
  • 将服务器证书导入另一个信任库(可能是
    lib/security/cacerts
    的本地副本),并使此特定应用程序使用此信任库。这可以使用
    javax.net.ssl.trustStore
    系统属性来完成
  • 让您的客户端应用程序使用配置为信任该证书的
    X509TrustManager
    初始化的
    SSLContext
    :手动编写的内容或来自
    TrustManagerFactory的信任管理器
    通过加载包含该特定证书的本地密钥库初始化(与前面的方法相同)
您将在中找到有关所有这些的更多详细信息


(应提供正确执行所有这些操作的详细信息,特别是
keytool-import…

要实现安全通信,您首先需要确保与正确的计算机进行通信。当客户端首次尝试建立安全连接时,它会ping服务器,服务器会使用其证书进行响应。此时,您必须验证服务器证书,然后才能继续进行。证书包括公钥和证书可用于确保证书有效的签名。例如,在web浏览器中,这意味着检查证书是否由浏览器设置中列为受信任的机构签名,如果检查失败,您将在浏览器中看到红色警告。在您的情况下,这意味着您已手动(或在代码中)签名将服务器证书添加到信任存储中以使其受信任。

不是这方面的专家,但我相信如果您要求证书提供特定公钥(而不是信任自签名或由特定颁发者签名),则可以避免中间人攻击。使用keytool修改密钥库似乎不现实,因为这超出了代码基础。我希望在运行时使用它,以便在运行时之后证书不在密钥库中。您可以使用第三种方法(请参阅链接中erickson的答案)如果您想将信任存储与代码一起分发,请从从类路径输入流加载的新密钥存储中加载信任存储。第二种方法通常不是什么大问题,正如我所说,制作
cacerts
的本地副本(或创建新密钥存储)并仅为该应用程序设置系统属性。它不必是影响所有应用程序的文件。它只是配置,您必须以某种方式进行配置。