为商业产品的组件提供安全的HTTP通信

Gar*_*son 10 java rest ssl ssl-certificate

假设我想发布一个商业产品,它有两个用Java编写的组件,使用RESTful API在本地网络上相互通信.它可能是一个音乐管理器,一个联系人数据库,一本食谱---重要的是这是一个合理且非常可能的场景.

请注意,我说的是两个组件通过本地网络相互通信 - 而不是与我的服务器进行通信.

那么如何确保通信安全?

我知道如果我为这个世界建立一个HTTP服务器,我可以(甚至便宜地)购买SSL证书.我做到了 但我不能告诉用户去购买证书---他们不知道我在说什么,也永远无法弄清楚如何安装它.

那我该怎么办?向每个人发送我自己的自签名证书并做一些非常糟糕的事情,如在Java中禁用证书验证?可怕,我知道.但至少信息不会以纯文本形式出现.

谁有更好的解决方案?

Rom*_*nev 6

更新于2015年9月20日, 以澄清评论中提出的观点

为了理解如何做到这一点,让我们检查一下这种应用程序的可能部署方案.假设有问题的应用程序包含两个组件 - 客户端部分和服务器部分,旨在安装在本地网络上的不同计算机上.我们希望我们的服务器部分仅接受安全连接,因此本地网络被认为是敌对的.

  1. 安装服务器部件.在安装时,使用目标计算机的主机名以编程方式创建自签名证书.如果计算机没有DNS记录(如myserver.mycorp.com),请使用其IP地址 - 它必须是静态的,因为我们需要将客户端部分指向它.您可以使用Bouncy Castle API在代码中创建证书.

  2. 将客户端部件安装到另一台计算机上,并将生成的证书复制到安装文件夹.手动执行此操作可有效地在服务器和客户端之间建立信任.尝试通过恶意网络上的未加密连接自动执行此操作将失败目的.

  3. 由于您确保在您自己的应用程序部分之间严格保密通信,因此您可以完全控制相关应用程序所信任的证书.在客户端上,创建密钥库,并将生成的证书添加到其中:

    FileInputStream fis = new FileInputStream(yourCertificateFile);
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509Certificate c = (X509Certificate)cf.generateCertificate(fis);
    
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(null, aRandomKeystorePasswordCharArray);
    ks.setCertificateEntry(aUniqueNameForYourCertificate, c);
    
    FileOutputStream fos = new FileOutputStream(aRandomKeystoreFileName);
    ks.store(fos, aRandomKeystorePasswordCharArray);
    fos.close();
    
    Run Code Online (Sandbox Code Playgroud)

    告诉JVM您的应用程序只会信任来自其自己的密钥库的证书.

    // replace backslashes '\' with slashes '/' in aRandomKeystoreFileName on Windows
    System.setProperty("javax.net.ssl.trustStore", aRandomKeystoreFileName);
    System.setProperty("javax.net.ssl.trustStorePassword", aRandomKeystorePassword);
    
    Run Code Online (Sandbox Code Playgroud)


小智 2

使用 OAuth 2.0 来保护您的服务,您应该只向客户端提供令牌,而不是双向 SSL。Facebook、Google 等都使用它。

https://en.wikipedia.org/wiki/OAuth