iOS:如何以编程方式从应用程序中的私钥和 x509 证书创建 PKCS12 (P12) 密钥库? [英] iOS: How to create PKCS12 (P12) keystore from private key and x509certificate in application programmatically?

查看:14
本文介绍了iOS:如何以编程方式从应用程序中的私钥和 x509 证书创建 PKCS12 (P12) 密钥库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题显然很相似,但没有任何答案:在不使用 OpenSSL 的情况下以编程方式为 iPhone 创建 x509 证书

This question was apparently similar but had no answers of any kind: Programmatically create a x509 certificate for iPhone without using OpenSSL

在我们的应用程序(服务器、客户端)中,我们正在实现客户端身份验证(基于 X509Certificate 的 SSL).我们已经有办法生成 keypair,创建 PKCS10 证书签名请求,由 self-signed CA 签名并创建一个X509Certificate,发回这个.但是,要在 SSL 请求中使用此证书,private keyX509Certificate 必须导出到 PKCS12 (P12) 密钥库.

In our application (server, client), we are implementing client authentication (SSL based on X509Certificate). We already have a way to generate a keypair, create a PKCS10 Certificate Signing Request, have this signed by the self-signed CA and create a X509Certificate, send this back. However, to use this certificate in SSL requests, the private key and the X509Certificate have to be exported to a PKCS12 (P12) keystore.

有没有人知道如何做到这一点,或者即使有可能?客户端必须生成P12文件(我们不想泄露私钥),客户端运行iOS,是移动设备.该解决方案适用于使用 BouncyCastle (SpongyCastle) 的 Android,但我们没有发现适用于 iOS.

Does anyone know anything about how to do this, or even if it's possible? The client has to generate the P12 file (we don't want to give out the private key), and the client is running iOS, and is a mobile device. The solution worked for Android using BouncyCastle (SpongyCastle), but we found nothing for iOS.

在 Java 中,此导出通过以下方式完成:

In Java, this export is done by the following:

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    KeyStore ks = KeyStore.getInstance("PKCS12", BouncyCastleProvider.PROVIDER_NAME);
    ks.load(null);
    ks.setKeyEntry("key-alias", (Key) key, password.toCharArray(),
            new java.security.cert.Certificate[] { x509Certificate });
    ks.store(bos, password.toCharArray());
    bos.close();
    return bos.toByteArray();

推荐答案

如果你使用openssl,你不必将完整的源代码复制到你的项目中,添加libs和headers就足够了,所以openssl库可以在没有任何大小问题的情况下使用.您可以使用 openssl 生成类似的密钥和证书:

If you use openssl, you don't have to copy the full source code into your project, it is enough to add the libs and headers, so the openssl library can be used without any size problem. You can generate a key and a cert like that with openssl:

EVP_PKEY * pkey;
pkey = EVP_PKEY_new();

RSA * rsa;
rsa = RSA_generate_key(
        2048,   /* number of bits for the key - 2048 is a sensible value */
        RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
        NULL,   /* callback - can be NULL if we aren't displaying progress */
        NULL    /* callback argument - not needed in this case */
);

EVP_PKEY_assign_RSA(pkey, rsa);

X509 * x509;
x509 = X509_new();

ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);

X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);

X509_set_pubkey(x509, pkey);

X509_NAME * name;
name = X509_get_subject_name(x509);

X509_NAME_add_entry_by_txt(name, "C",  MBSTRING_ASC,
        (unsigned char *)"CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O",  MBSTRING_ASC,
        (unsigned char *)"MyCompany Inc.", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
        (unsigned char *)"localhost", -1, -1, 0);

X509_set_issuer_name(x509, name);

//X509_sign(x509, pkey, EVP_sha1());

const EVP_CIPHER *aConst = EVP_des_ede3_cbc();

你可以用这些函数把它写成 pem 格式:

And you can write this into pem format with these functions:

PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL);


PEM_write_X509(
            f,   /* write the certificate to the file we've opened */
            x509 /* our certificate */
);

之后可以将这些文件写入一个 p12 文件,源代码来自这里:https://github.com/luvit/openssl/blob/master/openssl/demos/pkcs12/pkwrite.c

After that it is possible to write these files into a p12 file, source from here: https://github.com/luvit/openssl/blob/master/openssl/demos/pkcs12/pkwrite.c

/* pkwrite.c */

#include <stdio.h>
#include <stdlib.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>

/* Simple PKCS#12 file creator */
int main(int argc, char **argv)
{
    FILE *fp;
    EVP_PKEY *pkey;
    X509 *cert;
    PKCS12 *p12;
    if (argc != 5) {
        fprintf(stderr, "Usage: pkwrite infile password name p12file
");
        exit(1);
    }
    SSLeay_add_all_algorithms();
    ERR_load_crypto_strings();
    if (!(fp = fopen(argv[1], "r"))) {
        fprintf(stderr, "Error opening file %s
", argv[1]);
        exit(1);
    }
    cert = PEM_read_X509(fp, NULL, NULL, NULL);
    rewind(fp);
    pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);
    p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0,0,0,0,0);
    if(!p12) {
        fprintf(stderr, "Error creating PKCS#12 structure
");
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    if (!(fp = fopen(argv[4], "wb"))) {
        fprintf(stderr, "Error opening file %s
", argv[1]);
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    i2d_PKCS12_fp(fp, p12);
    PKCS12_free(p12);
    fclose(fp);
    return 0;
}

这篇关于iOS:如何以编程方式从应用程序中的私钥和 x509 证书创建 PKCS12 (P12) 密钥库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆