我有一个连接到后端rails应用程序的Android应用程序。我想加密我在设备和服务器之间发送的数据。我正在使用带密钥的基本加密。关键不是真正的秘密,因为我将它存储在apk上,因此,它很容易使用逆向工程和apk反编译技术。
我提出的是根据用户密码生成密钥。密钥需要具有固定长度,并且看到如何强制用户使用超长密码这不是一个选项,我正在做的是添加字符(基本上是我在旧的硬编码密钥中使用的字符)所以string(密码+字符)具有所需的长度。然后我加密所有参数(我使用JSON进行服务器 - 客户端通信),除了用户名(技术上不应该加密,所以这不是什么大问题)。当JSON请求到达服务器时,我使用username参数从数据库中获取用户的密码(基于服务器),然后构建我需要“解密/加密”我正在接收的数据的密钥/发送。这样,服务器/客户端之间的密钥总是相同的,但它对每个用户都是唯一的,这样我就不必在我的APK中存储一个易于获取的硬编码密钥。此外,密码不存储在设备中,用户每次要登录服务器时都需要输入密码。
我想知道的是,这种方法可以被认为是“体面安全”吗?
答案 0 :(得分:1)
您应该尝试查看https://en.m.wikipedia.org/wiki/RSA_(cryptosystem)您使用公钥(存储在应用程序中)来加密数据,然后服务器使用私钥(存储在服务器上)来解密数据。使用RSA,您无法使用公钥解密数据包,只能将其加密。所以它很安全。您应该为每个客户端创建密钥对(或密钥集)。
答案 1 :(得分:1)
从安全角度来看,您的方法看起来不错,但从用户体验的角度来看,可能质量较差。另外,为了从用户密码生成固定长度的字符串,您可以使用散列函数。
另一种方法是在运行时检索加密密钥并将其存储在Android Keystore中。访问Android密钥库对于攻击者来说访问密钥要困难得多。此外,此方法不要求用户在每次使用应用程序时都输入密码。但是,当您第一次交换对称密钥时,此方法受MitM attack的约束。要解决此问题,您应首先使用非对称加密方案来安全地交换对称密钥,然后您始终可以使用存储在密钥库中的密钥。
请注意,您不应使用非对称密码来加密/解密您的网络流量,因为非对称方法通常是处理器密集型的,并且特别是对于移动设备而言会耗尽电池。
但是在我看来,最好的方法是使用TLS解决方案。在TLS中同意预共享密钥(即对称密钥),使用RSA算法,然后使用对称算法对所有流量进行加密/解密。
答案 2 :(得分:0)
如果您需要,您可以随时使用基于密码的密钥派生算法: https://en.wikipedia.org/wiki/PBKDF2
但要考虑的是,您的密钥轮换时间表是否会自动与密码轮换时间表相同。
答案 3 :(得分:0)
您只需要客户端和服务器根据某些"密码"拥有相同的对称密钥,对吗?为什么不从每端的密码中获取密钥。
客户端将提示输入密码,然后创建良好的随机盐(每个连接都是唯一的),并使用大量迭代生成安全密钥。
然后,客户端将clear和iteration计数以明文形式发送给服务器。服务器查找其密码副本(假设您正在存储密码,而不是哈希),并使用salt和迭代生成匹配的对称密钥。
每个连接的唯一salt使得难以准备一组预先派生的密钥来尝试,并且高迭代计数导致对服务器执行字典攻击的巨大时间成本(即,尝试一定数量的密码)