我正在开发一款适用于GcdAsyncSocket并创建TLS连接的iPhone应用程序,我使用它们生成RSA密钥和CSR,并将CSR发送到服务器,服务器使用证书和其他一些类似公钥的证书进行响应。现在我需要与服务器建立另一个TLS连接并将私钥nd 2证书发回给它。我经历了很多帖子,但没有找到任何方法来实现这一目标。 如果有人可以提供帮助,并提供一些非常有帮助的代码。
感谢。
答案 0 :(得分:-1)
花了很多时间后,我能够使用开放的SSL库解决问题。我使用了以下代码
+(PKCS12*)convertToP12Certificate:(NSString*)certificate
certificateChain:(NSArray*)certificateChain
publicCertificate:(NSString*) publicCertificate
andPrivateKey:(NSString*)privateKey
{
//we create a x509 from primary certificate which goes as a single entity when creating p12
const char *cert_chars = [certificate cStringUsingEncoding:NSUTF8StringEncoding];
BIO *buffer = BIO_new(BIO_s_mem());
BIO_puts(buffer, cert_chars);
X509 *cert;
cert = PEM_read_bio_X509(buffer, NULL, 0, NULL);
if (cert == NULL) {
NSLog(@"error");
}
X509_print_fp(stdout, cert);
//create a evp from private key which goes as a separate entity while creating p12
const char *privateKey_chars = [privateKey cStringUsingEncoding:NSUTF8StringEncoding];
BIO *privateKeyBuffer = BIO_new(BIO_s_mem());
BIO_puts(privateKeyBuffer, privateKey_chars);
EVP_PKEY *evp;
evp =PEM_read_bio_PrivateKey(privateKeyBuffer, NULL, NULL, "Enc Key");
if (evp == NULL) {
NSLog(@"error");
}
if (!X509_check_private_key(cert, evp))
{
NSLog(@"PK error");
}
PKCS12 *p12;
SSLeay_add_all_algorithms();
ERR_load_crypto_strings();
const char *cert_chars2 = [publicCertificate cStringUsingEncoding:NSUTF8StringEncoding];
BIO *buffer2= BIO_new(BIO_s_mem());
BIO_puts(buffer2, cert_chars2);
X509 *cert2;
cert2 = PEM_read_bio_X509(buffer2, NULL, 0, NULL);
if (cert2 == NULL) {
NSLog(@"error");
}
X509_print_fp(stdout, cert2);
STACK_OF(X509) *sk = sk_X509_new_null();
sk_X509_push(sk, cert2);
for(NSString * tempCertificate in certificateChain)
{
const char *cert_chars3 = [tempCertificate cStringUsingEncoding:NSUTF8StringEncoding];
BIO *buffer3= BIO_new(BIO_s_mem());
BIO_puts(buffer3, cert_chars3);
X509 *cert3;
cert3 = PEM_read_bio_X509(buffer3, NULL, 0, NULL);
if (cert3 == NULL) {
NSLog(@"error");
}
X509_print_fp(stdout, cert3);
sk_X509_push(sk, cert3);
}
p12 = PKCS12_create(P12_Password, P12_Name, evp, cert, sk, 0,0,0,0,0);
return p12;
}
+(NSArray*)getCertificateChainForCertificate:(NSString*)certificate
certificateChain:(NSArray*)certificateChain
publicCertificate:(NSString*) publicCertificate
andPrivateKey:(NSString*)privateKey
{
PKCS12 *p12 = [CryptoHelper convertToP12Certificate:certificate
certificateChain:certificateChain
publicCertificate: publicCertificate
andPrivateKey:privateKey];
NSData *PKCS12Data = [CryptoHelper convertP12ToData:p12];
NSArray *certs = nil;
SecIdentityRef identityRef = nil;
CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
CFStringRef password = CFSTR(P12_Password);
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
CFRelease(options);
CFRelease(password);
if (securityError == errSecSuccess)
{
NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
if(certificateChain)
{
CFArrayRef certificates = (CFArrayRef)CFDictionaryGetValue(identityDict,kSecImportItemCertChain);
// There are 3 items in array when we retrieve certChain and for TLS connection cert
SecIdentityRef chainIdentity = (SecIdentityRef)CFArrayGetValueAtIndex(certificates,1);
certs = [[NSArray alloc] initWithObjects:(__bridge id)identityRef,(__bridge id)chainIdentity, nil];
}
else
{
certs = [[NSArray alloc] initWithObjects:(__bridge id)identityRef, nil];
}
} else
{
NSLog(@"Error opening Certificate.");
}
return certs;
}
我们可以将此数组传递给密钥GCDAsyncSocketSSLCertificates
的TLS连接。