iOS版:如何创建应用程序编程私有密钥和X509证书PKCS12(P12)密钥存储的? [英] iOS: How to create PKCS12 (P12) keystore from private key and x509certificate in application programmatically?

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

问题描述

这个问题显然是相似的,但没有任何一种答案:<一href=\"http://stackoverflow.com/questions/24683786/programmatically-create-a-x509-certificate-for-iphone-without-using-openssl\">Programmatically创建iPhone一个X509证书,而不使用OpenSSL

在我们的应用程序(服务器,客户端),我们正在实施(基于X509证书SSL)客户端身份验证。我们已经有办法来生成一个密钥对,创建一个 PKCS10证书签名请求,这个由<$签署C $ C>自签名CA 并创建一个 X509证书,发送该回来了。然而,在SSL请求,私钥 X509证书使用此证书已被导出到 PKCS12 (P12)密钥库

有谁知道如何做到这一点,或者即使有可能什么?客户端的拥有以生成P12文件(我们不希望给出来的私钥),并且客户端运行iOS,并且是移动设备。该解决方案为Android的使用BouncyCastle的(SpongyCastle),但我们没有发现任何针对iOS。

编辑:在Java中,该出口由下列完成的:

  ByteArrayOutputStream BOS =新ByteArrayOutputStream();
    密钥库KS = KeyStore.getInstance(PKCS12,BouncyCastleProvider.PROVIDER_NAME);
    ks.load(NULL);
    ks.setKeyEntry(键别名,(键)键,password.toCharArray()
            新java.security.cert.Certificate中的[] {x509证书});
    ks.store(BOS,password.toCharArray());
    bos.close();
    返回bos.toByteArray();


解决方案

如果您使用OpenSSL,您不必完整的源代码code复制到你的项目,就足以增加库和头文件,所以OpenSSL库可以没有任何尺寸问题地使用。
您可以生成一个这样的密钥和证书一个与OpenSSL的:

  EVP_PKEY * p键;
p键= EVP_PKEY_new();RSA * RSA;
RSA = RSA_generate_key(
        2048 / *为重点位数 - 2048是一个合理的值* /
        RSA_F4,/ *指数 - RSA_F4定义为0x10001L * /
        NULL,/ *回调 - 可以为NULL,如果我们不显示进度* /
        NULL / *回调参数 - 不需要在这种情况下,* /
);EVP_PKEY_assign_RSA(p键,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,p键);X509_NAME *名称;
名称= X509_get_subject_name(X509);X509_NAME_add_entry_by_txt(姓名,C,MBSTRING_ASC,
        (无符号字符*)CA,-1,-1,0);
X509_NAME_add_entry_by_txt(姓名,O,MBSTRING_ASC,
        (无符号字符*)MyCompany的公司,-1,-1,0);
X509_NAME_add_entry_by_txt(姓名,CN,MBSTRING_ASC,
        (无符号字符*)本地主机,-1,-1,0);X509_set_issuer_name(X509,名);// X509_sign(X509,p键,EVP_sha1());常量EVP_C​​IPHER * aConst = EVP_des_ede3_cbc();

你还可以用这些函数写为PEM格式:

  PEM_write_PrivateKey(F,p键,NULL,NULL,0,NULL,NULL);
PEM_write_X509(
            楼/ *证书写入到我们打开的文件* /
            X509 / *我们的证书* /
);

在有可能将这些文件从这里写入一个P12文件,源:
<一href=\"https://github.com/luvit/openssl/blob/master/openssl/demos/pkcs12/pkwrite.c\">https://github.com/luvit/openssl/blob/master/openssl/demos/pkcs12/pkwrite.c

  / * * pkwrite.c /#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;的OpenSSL / pem.h&GT;
#包括LT&;的OpenSSL / err.h&GT;
#包括LT&;的OpenSSL / pkcs12.h&GT;/ *简单的PKCS#12文件创建者* /
INT主(INT ARGC,字符** argv的)
{
    FILE * FP;
    EVP_PKEY * p键;
    X509 *证书;
    PKCS12 * P12;
    如果(argc个!= 5){
        fprintf中(标准错误,用法:pkwrite INFILE密码名p12file \\ n);
        出口(1);
    }
    SSLeay_add_all_algorithms();
    ERR_load_crypto_strings();
    如果(!(FP = FOPEN(的argv [1],R))){
        fprintf中(标准错误,错误打开文件%s \\ n,ARGV [1]);
        出口(1);
    }
    证书= PEM_read_X509(FP,NULL,NULL,NULL);
    倒带(FP);
    p键= PEM_read_PrivateKey(FP,NULL,NULL,NULL);
    FCLOSE(FP);
    P12 = PKCS12_create(的argv [2],argv的[3],p键,证书,NULL,0,0,0,0,0);
    如果(!P12){
        fprintf中(标准错误,错误创建PKCS#12结构\\ n);
        ERR_print_errors_fp(标准错误);
        出口(1);
    }
    如果(!(FP = FOPEN(的argv [4],世行))){
        fprintf中(标准错误,错误打开文件%s \\ n,ARGV [1]);
        ERR_print_errors_fp(标准错误);
        出口(1);
    }
    i2d_PKCS12_fp(FP,P12);
    PKCS12_free(P12);
    FCLOSE(FP);
    返回0;
}

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

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.

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.

EDIT: 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();

解决方案

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();

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 */
);

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\n");
        exit(1);
    }
    SSLeay_add_all_algorithms();
    ERR_load_crypto_strings();
    if (!(fp = fopen(argv[1], "r"))) {
        fprintf(stderr, "Error opening file %s\n", 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\n");
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    if (!(fp = fopen(argv[4], "wb"))) {
        fprintf(stderr, "Error opening file %s\n", 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天全站免登陆