2016-01-06 34 views
1

我在iPhone上的應用程序,在GcdAsyncSocket工作,並創建TLS連接的工作負載在TLS連接的證書,我生成使用這些RSA密鑰和CSR併發送CSR到服務器,服務器迴應的證書和其他一些證書就像公鑰一樣。現在我需要與服務器建立另一個TLS連接,並將私鑰和兩個證書發回給它。我經歷了很多帖子,但沒有找到任何方法來實現這一目標。 如果有人可以幫助,並與一些代碼,那將是很大的幫助。如何使用gcdasyncsocket

謝謝。

+0

嗨,你有沒有得到任何解決方案。你可以請張貼一些代碼,你如何加載證書並將其發送到服務器。我遇到了加載證書的問題。 – Gyanendra

回答

-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連接。