我什么时候应该使用 RSA 生成新的公钥和私钥?

信息安全 加密 网络 RSA 证书
2021-08-29 22:52:51

我正在创建一个巨大的在线手机游戏。我有几个问题要问你们,因为我在密码学和安全地通过网络发送数据方面的知识有点差。

一些细节:

  • 每个用户都有一个帐户
  • 要登录,您必须提供您的用户名和密码(通过应用程序,而不是网络浏览器)
  • 数据从客户端(移动设备)传输到某处的服务器。

简单的!好的,据我所知,正常的 Web 身份验证由 SSL 保护,这只是“发送纯文本,您是安全的”。

在移动设备上,我无法使用 SSL(即使 Android 提供了一些方法,我也无法将我的游戏移植到 iOS,使用不同的游戏/网络引擎等)。

我必须使“发送和接收”过程安全,这样第三个人就不会捕获用户的凭据。

正如我所读到的,执行此操作的最佳方法是RSA方法,它使用公钥和私钥来加密/解密数据包。

据我所知,它的工作原理如下:

  • 有两个密钥,私有、公共和消息:“消息”。
  • 任何人都可以获得公钥(因为它是公开的)
  • 只有服务器有权访问私钥
  • 任何人都可以用公钥加密“消息”,它看起来总是一样的(用相同的公钥加密的相同消息)
  • 加密的消息只能以一种方式解密 - 使用私钥,它看起来像第一条消息:“消息”。
  • 公钥和私钥不相等,但它们使用不同的加密/解密算法,所以它神奇地工作,最后消息是相同的

如果我错了,请纠正我!

这是我的问题:

  • 我在上面的例子中是否正确,以这种方式发送的数据包(并且公钥是真正公开的)是安全的(当然任何东西都可以解密)但是,你知道,它是“安全的”吗?
  • 每个用户都应该有自己的一对密钥吗?
  • 我应该什么时候生成一对新的密钥?每次登录?
  • 我应该什么时候向用户发送公钥?当他点击“注册”或“登录”时(已经用数据填充了文本字段)?或者当他打开应用程序时?

如果有人可以稍微解释一下这些事情,我将不胜感激!:)

@Luke Park 的另外两个问题

公钥是公开的,你说它不应该通过网络发送。这是否意味着使用公钥用户可以以某种方式解密数据?

第二个:您说我应该将公钥与应用程序捆绑在一起。如果公钥在黑客手中也是一种危险的工具,那么将其存储在代码中是否明智?据我所知,有一些方法可以从编译的程序中检索数据。

还有一个额外的!如果密钥是捆绑的(可能是硬编码的) - 它应该始终保持不变还是我应该改变这对(生成新的)?正如我在某处读到的,通过拥有一个“公开”的公钥,可以破解数据(这需要一些时间,但这是可能的)。

1个回答

总的来说,有一些误解,你说的是正确的。主要区别在于密文(例如,在您使用公钥加密消息之后)看起来并不总是相同,RSA 引入了一些随机数据和填充,导致生成的密文不同,即使明文相同。不过,这可能不会给您带来任何问题,但它有助于安全。

就个人而言,我认为让 TLS 工作所涉及的努力比实施您自己的解决方案更值得。但是,如果您确实想自己做...

我不会为每个用户生成一个新的密钥对。单个服务器密钥对就足够了。将公钥与您的应用程序一起分发,并将私钥保存在您的服务器上。使用 RSA 不是加密您的登录数据,而是协商一个 AES 密钥,然后使用它来加密您的数据。这是 TLS 使用的基本概念。这样做的原因之一是可以通过 RSA 加密的明文大小受密钥位大小的限制。如果不多次应用 RSA,通常无法加密超过 ~240 个字节,这在速度和安全性方面都是一个糟糕的主意。

请记住正确验证您的数据,使用 HMAC 或 GCM 等验证模式。否则,您的有效负载可能会在传输过程中被修改(而不是读取)。

不要将公钥发送到应用程序,它应该与应用程序捆绑在一起。如果您通过不安全的通道将公钥发送到应用程序,那么没有什么可以阻止它在传输过程中被修改。攻击者可以用他的公钥替换它,然后用他的私钥解密流量(和登录详细信息)。

我再说一遍,TLS 会比实现你自己的更好、更安全,但你似乎认为这是不可能的。

编辑:我说不要通过网络发送公钥,不是因为它在坏人手中是“危险的”或资产,而是因为您以明文形式发送公钥(例如通过原始 HTTP 或 TCP)。由于任何人都可以修改此流量(能够看到它不是问题),因此他们可以在该流量到达您的应用程序之前将其替换为自己的 OWN 公钥。如果密钥已经与应用程序捆绑在一起,那么双方都已经拥有了他们的密钥(例如,应用程序具有公共密钥,服务器具有私有密钥)。

除了加密和验证之外,公钥对任何人都没有用。这不是你需要隐藏的东西。您只需要能够验证它是正确的公钥。如果您将它与您的应用程序捆绑在一起,那么 App Store 和 Play Store 采用的安全性将足以将其与您的应用程序一起发送到用户设备。