如何将 RSA 私钥存储到后端给定的应用程序中?
How to store RSA Private Key into app given by backend?
我正在开发一个 android 应用程序,我必须在其中使用负载加密。对于这个后端,给我一个预先生成的密钥对(RSA Public 和私钥)用于加密和解密。
截至目前,我将这 2 个密钥(RSA public 和私有密钥)保存在硬编码的字符串中,但每个人都知道这不是一种安全的方法。
所以在这个过程中,客户端会发送使用服务器的public密钥加密的请求,服务器将使用自己的私钥解密它。并且响应只能由客户端的私钥解密,因为它是由客户端的 public 密钥加密的。
注意 - RSA public 和私钥对我的应用程序来说是静态的,我想将它放在安全的地方进行管理。
所以主要问题是我应该在我的应用程序中的什么地方保存 私钥。密钥在我的应用程序中是静态的,因为服务器人员将其分发给移动团队。而且我们不能使用我们自己生成的私钥。
那么在客户端保护第一次 givin 私钥的最佳方法是什么。
我累了this link & this,但是none适合我。
编码愉快:-)
应用程序应生成自己的密钥,然后将 public 密钥传输到后端。然后后端可以加密数据发送到应用程序。如果反方向需要加密,后台也可以生成一个key,将自己的publickey传给app加密
可能您应该将服务器方法更改为 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 也包含 public 密钥。
步骤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 });
如果您确实需要将私钥从服务器传输到设备,更安全的情况可能如下:
- 在设备上生成 AES 密钥。
- 首先获取服务器的 public 密钥。
- 使用 public 密钥包装生成的 AES 密钥。
- 将加密的 AES 密钥传输到服务器。
- 使用私钥在服务器端解密加密的 AES 密钥。
- 使用 AES 密钥加密私钥,并将其传输到设备。
问题已更新,所以更新答案:
如果您必须在应用程序中保留 public 私钥对,我建议使用 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/
我正在开发一个 android 应用程序,我必须在其中使用负载加密。对于这个后端,给我一个预先生成的密钥对(RSA Public 和私钥)用于加密和解密。
截至目前,我将这 2 个密钥(RSA public 和私有密钥)保存在硬编码的字符串中,但每个人都知道这不是一种安全的方法。
所以在这个过程中,客户端会发送使用服务器的public密钥加密的请求,服务器将使用自己的私钥解密它。并且响应只能由客户端的私钥解密,因为它是由客户端的 public 密钥加密的。
注意 - RSA public 和私钥对我的应用程序来说是静态的,我想将它放在安全的地方进行管理。
所以主要问题是我应该在我的应用程序中的什么地方保存 私钥。密钥在我的应用程序中是静态的,因为服务器人员将其分发给移动团队。而且我们不能使用我们自己生成的私钥。
那么在客户端保护第一次 givin 私钥的最佳方法是什么。
我累了this link & this,但是none适合我。
编码愉快:-)
应用程序应生成自己的密钥,然后将 public 密钥传输到后端。然后后端可以加密数据发送到应用程序。如果反方向需要加密,后台也可以生成一个key,将自己的publickey传给app加密
可能您应该将服务器方法更改为 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 也包含 public 密钥。
步骤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 });
如果您确实需要将私钥从服务器传输到设备,更安全的情况可能如下:
- 在设备上生成 AES 密钥。
- 首先获取服务器的 public 密钥。
- 使用 public 密钥包装生成的 AES 密钥。
- 将加密的 AES 密钥传输到服务器。
- 使用私钥在服务器端解密加密的 AES 密钥。
- 使用 AES 密钥加密私钥,并将其传输到设备。
问题已更新,所以更新答案:
如果您必须在应用程序中保留 public 私钥对,我建议使用 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/