如何将RSA私钥存储到后端给出的应用程序中?

时间:2018-02-16 04:57:47

标签: java android encryption android-keystore

我正在开发一个Android应用程序,我必须使用有效负载加密。对于这个后端,给我一个预先生成的密钥对(RSA公钥和私钥)进行加密和解密。

截至目前,我将这2个密钥(RSA公共密钥和私有密钥)保存在字符串中,但是每个人都知道这不是一种安全的方法。

因此,在此过程中,客户端将使用服务器的公钥发送加密的请求,服务器将使用自己的私钥对其进行解密。并且响应只能由客户端的私钥解密,因为它是由客户端的公钥加密的。

注意 - RSA public&私钥对我的应用来说是静态的,我希望将它放在一个安全的地方。

所以主要问题是我应该在应用中保留私钥。密钥在我的应用中是静态的,因为服务器人员将其分发给移动团队。我们不能使用自己生成的私钥。

那么在客户端首次获得第一次保存私钥的最佳方法是什么。

我累了this链接& this,但没有一个适合我。

快乐编码: - )

2 个答案:

答案 0 :(得分:3)

应用程序应生成自己的密钥,然后将公钥传输到后端。然后后端可以加密数据以发送到应用程序。如果需要在另一个方向进行加密,后端还可以生成密钥并将其公钥传输到应用程序进行加密。

答案 1 :(得分:2)

可能您应该将服务器方法更改为public key exchange并在Android设备上单独生成密钥。这种方式会非常安全。

您必须在KeyStore中存储包含证书的私钥。以下是您如何实现这一目标的步骤:

第1步。解码Base64 PKCS#8以获取PrivateKey的实例:

PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(ks);

第2步。案例可能是您的服务器发送带有私钥的证书,或者PKCS#8 blob也包含公钥。

第3步。如果服务器未发送证书,您需要为私钥生成证书。 Here是使用BouncyCastle的示例。

第4步。在KeyStore上存储密钥:

X509Certificate certificate = ... // get certificate for private key or generate
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
keystore.setKeyEntry("MyAlias", privateKey, null, new Certificate[] { certificate });

如果您真的必须从服务器向设备传输私钥,可能会出现更安全的情况:

  1. 在设备上生成AES密钥。
  2. 首先获取服务器的公钥。
  3. 使用该公钥包装生成的AES密钥。
  4. 将加密的AES密钥传输到服务器。
  5. 使用私钥解密服务器端的加密AES密钥。
  6. 使用AES密钥加密私钥,并将其传输到设备。
  7. 问题已更新,因此更新了答案:

    如果你必须在应用程序中保留公共私钥对,我建议使用Android NDK保留密钥字节,并强烈模糊它。

    但是,如果我是你,因为混淆工具对于强大的Android C ++代码加密来说是昂贵的,我会在服务器端保留这些静态密钥,而不是在应用程序内部硬编码。然后,我使用我之前提到的使用对称加密的步骤将静态密钥发送到设备。

    但是如果你选择使用NDK选项,它比将密钥存储在文件或Java代码上要好,但不完全是防弹的。用户打开应用程序后,您可以将从C ++代码中检索到的密钥存储在KeyStore中,这样就可以确保它安全。

    因此,如果您想使用最快的选项来保持应用程序二进制文件中的私钥安全,请选择NDK选项,以后您可以对其进行模糊处理。如果你有时间做一些服务器端安排来传输私钥,然后存储在密钥库中,那就去我写的步骤。

    以下资源可能对NDK有所帮助:

    https://androidsecurity.info/2016/12/15/storing-your-secure-information-in-the-ndk/

    https://medium.com/@abhi007tyagi/storing-api-keys-using-android-ndk-6abb0adcadad/