繁体   English   中英

从 android 到自定义套接字服务器的 SSL/TLS 连接

[英]SSL/TLS connection from android to a Custom Socket Server

完成了在 erlang 中使用 gen_tcp(简单套接字)和 Android 客户端应用程序进行测试的简单聊天服务器的编码。

现在我需要实现 SSL/TLS。

我将连接(发送和接收数据)部分保留在一个模块中,几行代码我可以轻松升级。

我之前没有实施 SSL/TLS 的经验,所以我在这里很困惑(就像很多一样)。

问题 - 测试部分(本地主机):

我可以通过以下方式生成自签名证书:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

这导致两个文件, key.pemcert.pem ,我的理解是一个是服务器证书,另一个是密钥文件,但是

  1. 证书颁发机构文件在哪里? 我需要生成一个吗? 我需要一个吗?
  2. 它们是否足以测试我的应用程序,使其为发布做好准备?
  3. 如何将我的简单 android 插座变成安全插座? (首选科特林)
  4. 我可以以编程方式信任我的自签名证书(并且只有那个)还是我需要将其安装在我的设备上(以及任何其他设备,如朋友的设备)

问题 - 生产部分:

  1. 我应该在我的服务器上使用我的自签名证书吗? 我需要创建 CA 吗? 使用自签名证书的优缺点?

  2. 我可以永远使用像letsencrypt这样的免费证书吗? 优点和缺点?

最后:

  1. 我也需要客户的证书吗? 我是否需要为 Android 应用程序提供某种密钥?

  2. 我能做些什么来保护我的应用程序免受 MITM 攻击(或保护我的应用程序不泄露服务器发送/接收的内容),例如这种类型的攻击

由于没有人回答,我将尝试发表我对此的看法:

证书颁发机构文件在哪里? 我需要生成一个吗? 我需要一个吗?

只要您的 Android(或任何其他)客户端将使用的唯一服务器是您自己的服务器,您就不需要让 CA 签署您的证书。 服务器使用服务器端证书向客户端(例如 web 浏览器)证明其身份(即证明它确实是它假装的身份)。 因此,只要您的客户端连接到同一主机(它预先拥有的证书),您就不需要任何签名(既不需要 CA 也不需要自签名)

它们是否足以测试我的应用程序,使其为发布做好准备?

由于您使用了最安全的 RSA(4096 位),我看不出可以对您生成的证书进行任何其他改进,所以是的,您可以认为它已准备好发布

如何将我的简单 android 插座变成安全插座? (首选科特林)

我从未使用过 Kotlin,但在 Java 环境中,它很简单:

import javax.net.ssl.*;
import java.security.*;

SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket)factory.createSocket("host", port);

我可以以编程方式信任我的自签名证书(并且只有那个)还是我需要将其安装在我的设备上(以及任何其他设备,如朋友的设备)

您可以将cert.pem添加到密钥库文件中(假设存储类型为 JKS 且密码为passw ):

keytool -importcert -file cert.pem -keystore keystore.jks -storetype JKS -alias "alias" -storepass passw

然后将keystore.jks放入您的应用程序的raw文件夹中,从而使其可以在您的代码中作为R.raw.keystore访问:

    KeyStore trusted = KeyStore.getInstance("JKS");
    InputStream in = context.getResources().openRawResource(R.raw.keystore); //open inputstream for keystore file in "raw" folder
    trusted.load(in, "passw".toCharArray());                                 //load the keystore from file (using password specified when certificate was imported into keystore)       
    in.close();                                                              //close inputstream 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(trusted, "passw".toCharArray());
    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");               //configure SSL Context to use TLS v1.2 
    sslContext.init(kmf.getKeyManagers(),null,null);
    SSLSocketFactory factory = sslContext.getSocketFactory();

然后您以上述方式使用factory打开安全 sockets

我应该在我的服务器上使用我的自签名证书吗? 我需要创建 CA 吗? 使用自签名证书的优缺点?

见答案 1

我可以永远使用像letsencrypt这样的免费证书吗? 优点和缺点?

这完全取决于特定 CA 受到损害的风险有多大,即签署欺诈性证书。 尽管成本更高,但使用值得信赖的 CA 总是更好

我也需要客户的证书吗? 我是否需要为 Android 应用程序提供某种密钥?

客户端证书只是验证最终用户的另一种方式。 如果您已经使用密码进行身份验证,则不需要使用客户端证书(您实际上可以添加它以提高安全性,但大多数情况下没有必要,除了有人可能会窃取它)

我可以做些什么来保护我的应用程序免受 MITM(或保护我的应用程序不泄露服务器发送/接收的内容),例如这种类型的攻击

好吧,只要设备属于其原始所有者就可以了。 如果它被盗并且小偷知道该代理并可能泄露请求/响应内容,则会出现风险。 除了用户尽快更改他/她的密码之外,我没有想到其他任何事情

接受的答案很好但不完整。

证书颁发机构文件在哪里? 我需要生成一个吗? 我需要一个吗?

它是公钥基础设施的一部分。 “公共”一词在这里很有趣:如果您的服务器不会被除您之外的任何人使用,那么为第三方 CA 证书付费就没有多大意义。 这些适用于为大量公共用户部署的域,因此容易受到攻击和漏洞的影响。

我应该在我的服务器上使用我的自签名证书吗? 我需要创建 CA 吗? 使用自签名证书的优缺点?

现在泡菜来了:如果你使用第三方CA证书,它会花钱,但它可以通过移动设备和开箱即用的浏览器公开访问,即默认的SSL套接字工厂将能够与你的连接领域。

如果您选择自签名证书,则移动设备或浏览器无法与您的域完成 SSL 握手(即无法连接),除非进行以下更改之一:

  • 指示您的套接字工厂忽略 SSL 验证
  • 创建一个可以识别您的证书的套接字工厂
  • 将您创建的自签名证书添加到客户端设备(移动/桌面浏览器)上的已知证书列表中。
  • 使用称为SSL 固定的技术来测试握手和连接。

我也需要客户的证书吗? 我是否需要为 Android 应用程序提供某种密钥?

您所说的被称为双向或双向 SSL 验证 这很好,但可选。 在您的服务器上拥有一个公开的 CA 证书是必要且足够的。

如何将我的简单 android 插座变成安全插座?

默认套接字是安全套接字,至少对于任何健全的 TCP/HTTP 库都是如此。 您必须更改代码以告诉套接字工厂忽略 SSL 验证。

它们是否足以测试我的应用程序,使其为发布做好准备?

嗯,这有点不清楚。 您应该使用 SSL 固定或已知 CA 证书进行测试,而不是使用自签名证书。 如果您只想测试您的应用功能,您可以禁用 SSL 验证。 据我了解,发布应用程序将需要默认(即安全)套接字工厂,该工厂使用公认的第三方 CA 证书自动管理 SSL 握手。

我可以以编程方式信任我的自签名证书(并且只有那个)还是我需要将其安装在我的设备上(以及任何其他设备,如朋友的设备)

是的,它可以安装在客户端设备/浏览器上。 但是,您的服务器只能通过该设备/浏览器进行通信。

最后一点

如果您使用自签名证书在 Play Store 上发布应用程序,或者禁用或忽略 SSL 验证,您很快就会收到 email警告,提示您的应用程序将被删除。 祝你好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM