2012-06-13 26 views
7

Những gì tôi đang cố gắng làm là tái chạy lệnh sau đây thông qua Terminal trên máy Mac, nhưng trên iPhone/trong Cocoa:Replicate OpenSSL smime lệnh trên iPhone/Cocoa

openssl smime -binary -sign -signer cert.pem -inkey key.pem -in file.txt -out encrypted -outform DER 

nơi "mã hóa" là tệp được mã hóa kết quả từ lệnh.

Mặc dù nó chỉ định 2 khóa riêng biệt (khóa công cộng và khóa riêng), có thể có các khóa này dưới dạng tệp .p12 duy nhất.

Sau khi theo dõi this đoạn mã ca cao để mã hóa tệp bằng chứng chỉ .p12, tôi không chắc liệu đây có phải là cách phù hợp hay không.

Cách tiếp cận tốt nhất để sao chép lệnh smime trên iPhone (theo lệnh Terminal ở trên), hoặc là không thể thực hiện được thông qua các phương thức có sẵn Security.framework/CommonCrypto?

+0

Không biết câu trả lời nhưng may mắn trên ứng dụng PassKit của bạn! –

Trả lời

3

Theo như tôi biết - bạn là một chút lên một con lạch - với mái chèo bị nhốt trong appstore.

  • iOS thiếu CMSEncoderAddSigners, CMSEncoderUpdateContent, CMSEncoderCopyEncodedNội dung bạn cần cho điều này.
  • Sử dụng openssl hoặc Chilkat cũng không lý tưởng - vì API keychain của iOS không cung cấp cho bạn quyền truy cập (nữa) vào khóa riêng tư sau khi được nhập.

Tôi đã giải quyết vấn đề này trong quá khứ với cả openssl và Chilkat.

Trong mỗi trường hợp, tôi 'lưu' bản sao khóa cá nhân - như khi nó đi vào móc khóa - tất cả những gì tôi có thể quay lại là SecKeyRef (bạn cần phải ký một thỏa thuận/quyền bổ sung với táo có thể lấy nó ra và vẫn ở trong appstore, ngược lại, bất kỳ kỹ sư nào của VPN (ví dụ: trình bách khoa toàn thư) ứng dụng để xem các phương thức/khung liên kết).

Đối với openssl - chỉ cần lấy mã smime.c trong các ứng dụng của openssl và sửa đổi. Đối với những thứ Chilkat là đơn giản hơn rất nhiều:

CkoCert * mine = [identity ckoCert]; 

    assert([mime AddEncryptCert: mine] == YES); 

    for(id cc in backupCerts) { 
     assert([mime AddEncryptCert:cc] == YES); 
    } 

    for(id key in [headers allKeys]) { 
     [mime SetHeaderField:[NSString stringWithFormat:@"%s%@", X_HDR_PREFIX, key] 
         value:[headers objectForKey:key] 
     ]; 
    }; 

    [mime SetBodyFromBinary:data];   
    assert([mime EncryptN] == YES); 

    return [mime GetMimeBytes]; 

và nơi mà các lĩnh vực nhận dạng có 'giữ bộ nhớ cache của riêng bạn' cheat:

-(id)initWithPKCS12:(NSData*)pkcs12der password:(NSString *)password { 
    if (password == nil) 
     password = [APPSETTINGS wellKnownPkcsPassword]; 

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          password, kSecImportExportPassphrase, 
          nil]; 

    CFArrayRef items; 
    OSStatus status = SecPKCS12Import((__bridge CFDataRef)pkcs12der, 
     (__bridge CFDictionaryRef)options, &items); 

    if (status != noErr) { 
     NSLog(@"PKCS12 importAsDer failed: Error %ld",(long)status); 
     ... 
    } 

    if (!items || CFArrayGetCount(items) < 1) { 
     NSLog(@"PKCS12 importAsDer failed - nothing returned (%ld bytes DER)", 
       (long)[pkcs12der length]); 
     ... 
    } 

    CFDictionaryRef dict0 = (CFDictionaryRef) CFArrayGetValueAtIndex(items, 0); 
    if (!dict0) 
     return nil; 

    SecIdentityRef iRef = (SecIdentityRef) CFDictionaryGetValue(dict0, 
      kSecImportItemIdentity); 
    CFArrayRef cRef = (CFArrayRef) CFDictionaryGetValue(dict0, kSecImportItemCertChain); 

    self = [self initWithIdentityRef:iRef withChainArrayRef:cRef]; 
    CFRelease(items); 

#if TARGET_OS_IPHONE 
    // We lack SecPrivate* on iOS. So we cheat a bit - rather than 
    // use the keychain we limt ourselves to our own *.p12's and 
    // keep a copy of the private key in memory. 
    // 
# ifdef WITH_OPENSSL 

    const unsigned char * ptr = [pkcs12der bytes]; 
    PKCS12 * p12 = d2i_PKCS12(NULL, &ptr, len); 
    char buff[1024]; 

    if (!p12) { 
     NSLog(@"Could not decode PKCS#12: %s", ERR_error_string(ERR_get_error(), buff)); 
     ... 
    }; 

    const char * pass = [password cStringUsingEncoding:NSASCIIStringEncoding]; 

    if (PKCS12_parse(p12, pass, &pkey, &x509, NULL) != 1) { 
     NSLog(@"Could not parse PKCS#12: %s", ERR_error_string(ERR_get_error(), buff)); 
     ... 
    }; 
    .... 
# else 
    ckoCert = [[CkoCert alloc] init]; 

    if (!([ckoCert LoadPfxData:pkcs12der password:[APPSETTINGS wellKnownPkcsPassword]])) { 
     NSLog(@"PKCS12 loadPfxData failed: %@", [ckoCert LastErrorText]); 
     ... 
    } 

    ckoPrivateKey = [ckoCert ExportPrivateKey]; 
# endif // chilkat or openssl 
#endif // iOS 

    return self; 
} 

Cảnh báo: trong trên tôi đã tước nhất quản lý mngt/lỗi và/hoặc thay thế nó bằng cách khẳng định nếu không nó sẽ có một chút quá tốn kém.

Xin cảm ơn,

Dw.

Các vấn đề liên quan