为 android 个应用程序提供私钥和证书
Provide private key and certificate for android app
我的应用需要使用网络服务,我想使用证书对服务器进行身份验证。
但是,将带有签名密钥的密钥库嵌入包中被认为是不好的做法(并明确警告:https://developer.android.com/google/play/asi)因为它可以被提取和解密。
我可以使用 android 提供的密钥库生成私钥并使用它 - 但我仍然需要对其进行签名以便在服务器端对其进行验证。
理想情况下应该有证书链,具有受信任的根权限并包含我可以在服务器端验证的已签名应用程序包的元数据。
或者是否可以在证书生成过程中使用包签名来证明自签名证书源自未篡改的包?
坏人(“Trudy”)可以刷新任何自定义 Android ROM,包括在 APK 安装期间删除包证书验证的 ROM。因此,您的应用对其 Android 主机 OS 进行的任何查询本质上都是对 Trudy 的请求。
因此,有可能发现带有纯正 OS 的被黑 APK 的安装。但是有了掺假的 OS,所有赌注都被取消了。
我认为客户端自我验证的任何解决方案都需要对主机进行权威验证 OS。不容易。
Is it somehow possible to use package signature in certificate
generation process to prove that self signed certificate originated
form untampered package?
(1) 你的意思是每个客户端在安装后生成不同的自签名证书,并以某种方式将其与 apk 包签名交叉引用以进行身份验证?那么不,这不会阻止 Trudy。 (而且它在身份验证中也没有用。)
(2) 你的意思是客户端有一个嵌入在APK中的通用私钥,并且可以使用包证书上的元数据来验证私钥?我不知道包证书元数据中是否有任何可用字段可以添加此信息。这是您建议的一种有趣的方法。然而,由于 Trudy 可能是 OS,理论上 Trudy 可以模拟它希望的任何结果。我看不出这会阻止 Trudy。
Proguard 开发人员的这个 (SO) post 提供了 5 个选项来处理您的 Android 应用中的秘密。他指出:
Intrinsically, nothing on the client-side is unbreakable, but you can
certainly raise the bar.
我知道您希望使用用户的私钥对 Web 服务 (API) 进行用户身份验证,并且签名的令牌将在服务器上使用用户的证书或已在此处注册的 public 密钥进行验证用户注册时间。
您是希望使用外部 USB 令牌安全地存储私钥,还是希望将私钥存储在 Android 设备内存中?
我们已经在桌面上处理过此类要求(示例位于 https://web.signer.digital/Home),但未在 Android 上处理过。我知道我们可以使用 OTG USB 将 USB 加密令牌(如 ePass2003 或其他)连接到 Android 设备,并且可以从 Android 访问某些设备的 Android 驱动程序,但没有用实际上。但这可以作为你研究的方向。
移动应用程序是 public 应用程序,因为最终用户可能会查看和修改应用程序代码。因此,您的应用程序无法对恶意用户保密。这包括客户端证书,这是相互 TLS (mTLS) 所必需的。
将任何客户端证书存储在 Android 设备上以进行机器对机器(不要将 machine to machine
与 user to machine
混合)mTLS 身份验证是不安全的。它可以导出,然后供任何用户在其他设备上使用。
操作系统(Android 还有一些浏览器,例如 Firefox 可能有自己的)提供证书存储,其中存储 CA 证书和可以存储客户端证书。
最好在此处存储用户(为用户颁发,而不是为 app/machine)客户端证书。然后移动应用程序应该可以选择 select 哪些用户客户端证书应该用于 mTLS。但是 I want to authenticate my application without any user interaction.
是不可能的。至少必须有初始用户交互:用户客户端证书导入客户端存储、mTLS 应用程序配置。恕我直言,这是最好的和安全的 mTLS 实施。现实世界的例子:Rocket Chat app.
您要求基于反向 TLS 的验证?通常,客户端会验证 Web 服务,因为客户端的主机 OS 信任特定的 CA 证书,该证书也用于生成 Web 服务 TLS 证书。
区别是:
web servers are protected and controlled by authors. Client devices are not. So, having a private key in app to sign the data sent to server is futile.
不过,您可以探索 Google's Licensing implementation 服务器端验证,以强制合法安装和许可的应用程序可以联系服务器。
我的应用需要使用网络服务,我想使用证书对服务器进行身份验证。
但是,将带有签名密钥的密钥库嵌入包中被认为是不好的做法(并明确警告:https://developer.android.com/google/play/asi)因为它可以被提取和解密。
我可以使用 android 提供的密钥库生成私钥并使用它 - 但我仍然需要对其进行签名以便在服务器端对其进行验证。
理想情况下应该有证书链,具有受信任的根权限并包含我可以在服务器端验证的已签名应用程序包的元数据。
或者是否可以在证书生成过程中使用包签名来证明自签名证书源自未篡改的包?
坏人(“Trudy”)可以刷新任何自定义 Android ROM,包括在 APK 安装期间删除包证书验证的 ROM。因此,您的应用对其 Android 主机 OS 进行的任何查询本质上都是对 Trudy 的请求。
因此,有可能发现带有纯正 OS 的被黑 APK 的安装。但是有了掺假的 OS,所有赌注都被取消了。
我认为客户端自我验证的任何解决方案都需要对主机进行权威验证 OS。不容易。
Is it somehow possible to use package signature in certificate generation process to prove that self signed certificate originated form untampered package?
(1) 你的意思是每个客户端在安装后生成不同的自签名证书,并以某种方式将其与 apk 包签名交叉引用以进行身份验证?那么不,这不会阻止 Trudy。 (而且它在身份验证中也没有用。)
(2) 你的意思是客户端有一个嵌入在APK中的通用私钥,并且可以使用包证书上的元数据来验证私钥?我不知道包证书元数据中是否有任何可用字段可以添加此信息。这是您建议的一种有趣的方法。然而,由于 Trudy 可能是 OS,理论上 Trudy 可以模拟它希望的任何结果。我看不出这会阻止 Trudy。
Proguard 开发人员的这个 (SO) post 提供了 5 个选项来处理您的 Android 应用中的秘密。他指出:
Intrinsically, nothing on the client-side is unbreakable, but you can certainly raise the bar.
我知道您希望使用用户的私钥对 Web 服务 (API) 进行用户身份验证,并且签名的令牌将在服务器上使用用户的证书或已在此处注册的 public 密钥进行验证用户注册时间。
您是希望使用外部 USB 令牌安全地存储私钥,还是希望将私钥存储在 Android 设备内存中?
我们已经在桌面上处理过此类要求(示例位于 https://web.signer.digital/Home),但未在 Android 上处理过。我知道我们可以使用 OTG USB 将 USB 加密令牌(如 ePass2003 或其他)连接到 Android 设备,并且可以从 Android 访问某些设备的 Android 驱动程序,但没有用实际上。但这可以作为你研究的方向。
移动应用程序是 public 应用程序,因为最终用户可能会查看和修改应用程序代码。因此,您的应用程序无法对恶意用户保密。这包括客户端证书,这是相互 TLS (mTLS) 所必需的。
将任何客户端证书存储在 Android 设备上以进行机器对机器(不要将 machine to machine
与 user to machine
混合)mTLS 身份验证是不安全的。它可以导出,然后供任何用户在其他设备上使用。
操作系统(Android 还有一些浏览器,例如 Firefox 可能有自己的)提供证书存储,其中存储 CA 证书和可以存储客户端证书。
最好在此处存储用户(为用户颁发,而不是为 app/machine)客户端证书。然后移动应用程序应该可以选择 select 哪些用户客户端证书应该用于 mTLS。但是 I want to authenticate my application without any user interaction.
是不可能的。至少必须有初始用户交互:用户客户端证书导入客户端存储、mTLS 应用程序配置。恕我直言,这是最好的和安全的 mTLS 实施。现实世界的例子:Rocket Chat app.
您要求基于反向 TLS 的验证?通常,客户端会验证 Web 服务,因为客户端的主机 OS 信任特定的 CA 证书,该证书也用于生成 Web 服务 TLS 证书。
区别是:
web servers are protected and controlled by authors. Client devices are not. So, having a private key in app to sign the data sent to server is futile.
不过,您可以探索 Google's Licensing implementation 服务器端验证,以强制合法安装和许可的应用程序可以联系服务器。