Gar*_*son 10 java rest ssl ssl-certificate
假设我想发布一个商业产品,它有两个用Java编写的组件,使用RESTful API在本地网络上相互通信.它可能是一个音乐管理器,一个联系人数据库,一本食谱---重要的是这是一个合理且非常可能的场景.
请注意,我说的是两个组件通过本地网络相互通信 - 而不是与我的服务器进行通信.
那么如何确保通信安全?
我知道如果我为这个世界建立一个HTTP服务器,我可以(甚至便宜地)购买SSL证书.我做到了 但我不能告诉用户去购买证书---他们不知道我在说什么,也永远无法弄清楚如何安装它.
那我该怎么办?向每个人发送我自己的自签名证书并做一些非常糟糕的事情,如在Java中禁用证书验证?可怕,我知道.但至少信息不会以纯文本形式出现.
谁有更好的解决方案?
更新于2015年9月20日, 以澄清评论中提出的观点
为了理解如何做到这一点,让我们检查一下这种应用程序的可能部署方案.假设有问题的应用程序包含两个组件 - 客户端部分和服务器部分,旨在安装在本地网络上的不同计算机上.我们希望我们的服务器部分仅接受安全连接,因此本地网络被认为是敌对的.
安装服务器部件.在安装时,使用目标计算机的主机名以编程方式创建自签名证书.如果计算机没有DNS记录(如myserver.mycorp.com),请使用其IP地址 - 它必须是静态的,因为我们需要将客户端部分指向它.您可以使用Bouncy Castle API在代码中创建证书.
将客户端部件安装到另一台计算机上,并将生成的证书复制到安装文件夹.手动执行此操作可有效地在服务器和客户端之间建立信任.尝试通过恶意网络上的未加密连接自动执行此操作将失败目的.
由于您确保在您自己的应用程序部分之间严格保密通信,因此您可以完全控制相关应用程序所信任的证书.在客户端上,创建密钥库,并将生成的证书添加到其中:
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
| 归档时间: |
|
| 查看次数: |
276 次 |
| 最近记录: |