这个问题显然很相似,但没有任何答案:
Programmatically create a x509 certificate for iPhone without using OpenSSL
在我们的应用程序(服务器,客户端)中,我们正在实现客户端身份验证(基于X509Certificate的SSL).我们已经有办法生成密钥对,创建PKCS10证书签名请求,由自签名CA签名并创建X509Certificate,然后发回.但是,要在SSL请求中使用此证书,必须将私钥和X509Certificate导出到PKCS12(P12)密钥库.
有没有人知道如何做到这一点,或者即使它可能?客户端必须生成P12文件(我们不想发出私钥),客户端正在运行iOS,并且是移动设备.该解决方案适用于Android使用BouncyCastle(SpongyCastle),但我们没有找到任何iOS.
编辑:在Java中,此导出由以下内容完成:
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,则不必将完整的源代码复制到项目中,只需添加lib和头文件即可,因此可以使用openssl库而不会出现任何大小问题.
您可以使用openssl生成密钥和证书:
您可以使用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,0); X509_NAME_add_entry_by_txt(name,"O",(unsigned char *)"MyCompany Inc.","CN",(unsigned char *)"localhost",0); X509_set_issuer_name(x509,name); //X509_sign(x509,pkey,EVP_sha1()); const EVP_CIPHER *aConst = EVP_des_ede3_cbc();
你可以用这些函数把它写成pem格式:
PEM_write_PrivateKey(f,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
/* 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); rewind(fp); pkey = PEM_read_PrivateKey(fp,NULL); fclose(fp); p12 = PKCS12_create(argv[2],argv[3],cert,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,argv[1]); ERR_print_errors_fp(stderr); exit(1); } i2d_PKCS12_fp(fp,p12); PKCS12_free(p12); fclose(fp); return 0; }