使用运行时 Android/Java 可用的客户端证书进行 TLS/SSL 客户端身份验证

发布于 2024-11-30 05:24:20 字数 256 浏览 0 评论 0原文

假设我有一个应用程序,它以某种方式在运行时通过安全通道检索客户端证书(私钥/公钥对)(因此我在构建时没有此客户端证书)。

如何使用此客户端证书进行客户端身份验证,而不使用 keytool 且不使用持久/磁盘密钥库上的某些证书​​。所以我不想(实际上我不能)使用命令行 keytool 导入它?

实际上我想复制 libcurl 中完成的功能。您只需设置客户端证书(带有私钥)即可完成。它不涉及密钥库。

这一切都必须在 Java/Android 中完成。

Suppose I have an application which in some way retrieves a client certificate (private/public key pair) at runtime via a secure channel (so I don't have this client certificate at build time).

How can I use this client certificate for client authentication without using keytool and not using some on persistent/ondisk keystore. So I do not want (actually I can't) to import it using a command line keytool?

Actually I want to replicate the functionality done in libcurl. You just set the client certificate (with private key) and your done. It doesn't involve a keystore.

All this has to be done in Java/Android.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌生 2024-12-07 05:24:21

我刚刚开始工作,我认为您不会对我的答案感到非常满意,但它确实有效:)

因此,困难的部分是获得执行客户端身份验证所需的 pkcs12 证书,如果您的证书已经在 pkcs12 中,那么您已经解决了所有困难,您可以参考 Android 中的 SSL 客户端身份验证 以了解如何使用该证书。

如果您只有一对公钥而没有 pkcs12 证书,那么您需要制作一个。据我所知,java/android 中无法创建此证书,因此您需要使用 android NDK 和 openssl。

如果您从 https://github.com/guardianproject/openssl-android 你可以用它来构建 openssl。默认情况下,它编译为 .so 共享对象,但只有我尝试运行此代码的一些 Android 设备能够链接到 libcrypto,因此,尽管我确信有更好的方法,但我进入了 Android.mk 文件并在一些地方将 include $(BUILD_SHARED_LIBRARY) 替换为 include $(BUILD_STATIC_LIBRARY) ,以便我可以编译 .a 静态库。

然后我使用了 Android NDK: Link using a pre- 中的信息编译静态库以将我编译的 libcrypto.a 链接到我的本机代码。

此本机代码使用 openssl 首先创建 X509 证书,然后使用它创建 PKCS12 文件,该文件可以按照我之前提到的方式使用,位于 Android 中的 SSL 客户端身份验证

首先,您需要将公钥和私钥作为 EVP_PKEY 指针放入本地,这可以通过多种方式进行,基于根据您的密钥的格式,您可以使用以下代码创建 X509 证书

X509 *public_key_cert = X509_new();

X509_gmtime_adj(X509_get_notBefore(public_key_cert),0);
X509_gmtime_adj(X509_get_notAfter(public_key_cert), (long) 60*60*24*365);

X509_set_pubkey(public_key_cert,evp_pub_key);

这将创建最低限度有效的 X509 证书,有效期为 1 年。如果您要运行自己的证书颁发机构,您可能需要执行其他操作,例如签署证书,或者设置包含各种信息的大量标头中的任何一个。

接下来,您需要使用 X509 证书创建 pkcs12 证书,如下所示:

PKCS12 *pkcs12 = PKCS12_create(password, "Some Sort of Friendly Name", evp_priv_key, public_key_cert, NULL, 0, 0, 0, 0, 0);

密码是一个 char*,其中包含将用于使用三重 DES 加密私钥的密码

现在您已经有了 pkcs12 证书,您可以转到 Android 中的 SSL 客户端身份验证 并进行客户端身份验证。

祝你好运!

I just got this working and I dont think you'll be very happy with my answer but it does work :)

So the hard part is to get the pkcs12 certificate you need to perform client authentication, if your certificate is already in pkcs12 then you've got all the hard stuff out of the way and you can refer to the second answer on SSL client authentication in Android to see how to use that certificate.

if you just have a public private key pair and not a pkcs12 certificate then you will need to make one. As far as I could tell there is no way in java/android to create this certificate so you need to use the android NDK and openssl.

if you download the openssl-android project from https://github.com/guardianproject/openssl-android you can use it to build openssl. By default it compiles as a .so shared object but only some of the android devices I tried to run this code on were able to link against libcrypto, so, although im sure there is a better way I went into the Android.mk files and replaced include $(BUILD_SHARED_LIBRARY) with include $(BUILD_STATIC_LIBRARY) in a few places so that I could compile a .a static library.

I then used the info from Android NDK: Link using a pre-compiled static library to link the libcrypto.a I compiled to my native code.

This native code uses openssl to first create an X509 certificate and then uses it to create a PKCS12 file which can be used in the manner I mentioned before located at SSL client authentication in Android

first you need to get your public and private keys into native land as EVP_PKEY pointers which can happen in a variety of ways based on what format your keys are in then you can use the following code to create an X509 certificate

X509 *public_key_cert = X509_new();

X509_gmtime_adj(X509_get_notBefore(public_key_cert),0);
X509_gmtime_adj(X509_get_notAfter(public_key_cert), (long) 60*60*24*365);

X509_set_pubkey(public_key_cert,evp_pub_key);

This creates the most minimally valid X509 certificate which is valid for 1 year. You may want to do other stuff like sign the certificate if you are going to run your own certificate authority, or set any of a large set of headers which contain various bits of information.

next you need to create the pkcs12 certificate using the X509 cert like this:

PKCS12 *pkcs12 = PKCS12_create(password, "Some Sort of Friendly Name", evp_priv_key, public_key_cert, NULL, 0, 0, 0, 0, 0);

password is a char* containing the password which will be used to encrypt the private key using triple-DES

Now that you have a pkcs12 certificate you can go over to SSL client authentication in Android and get client authentication going.

Good Luck!

聊慰 2024-12-07 05:24:20

您可以在 Java 中通过定义自己的 KeyManager 来完成此操作,如 JSSE 参考指南。我无法为 Android 发言。

You can do it in Java by defining your own KeyManager as described in the JSSE Reference Guide. I can't speak for Android.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文