2014-02-12 37 views
19

如何使用RSA密鑰在iOS上簽名和驗證一些數據(最好使用系統自己的libcommonCrypto)?使用RSA在iOS上簽名和驗證

+0

RSA密鑰位於哪裏(由於公共和私密部分的驗證和簽名而複數)?他們是在鑰匙串中,還是在PEM或DER格式中是外部的? – jww

+0

正如問題中所述,我更願意使用libcommonCrypto。這意味着從程序員的角度來看,這個鍵可以用'SecKeyRef'(在內存引用中可能來自keychain,PEM或Apple Security Framework支持的其他東西)。這種密鑰對我的問題應該不重要,但目前我將所有密鑰(自己的私鑰和一些公鑰)存儲在設備沙盒化鑰匙串中。 – miho

+0

您是否試圖使用RSA使用公鑰/私鑰加密/解密一些數據? – jailani

回答

28

由於在StackOverflow和Apple文檔上找不到任何關於簽名和驗證的知識,我不得不在iOS頭文件中手動瀏覽並找到SecKeyRawSignSecKeyRawVerify。以下代碼行似乎工作。


NSData的簽名(使用RSA SHA256):

NSData* PKCSSignBytesSHA256withRSA(NSData* plainData, SecKeyRef privateKey) 
{ 
    size_t signedHashBytesSize = SecKeyGetBlockSize(privateKey); 
    uint8_t* signedHashBytes = malloc(signedHashBytesSize); 
    memset(signedHashBytes, 0x0, signedHashBytesSize); 

    size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH; 
    uint8_t* hashBytes = malloc(hashBytesSize); 
    if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], hashBytes)) { 
     return nil; 
    } 

    SecKeyRawSign(privateKey, 
        kSecPaddingPKCS1SHA256, 
        hashBytes, 
        hashBytesSize, 
        signedHashBytes, 
        &signedHashBytesSize); 

    NSData* signedHash = [NSData dataWithBytes:signedHashBytes 
             length:(NSUInteger)signedHashBytesSize]; 

    if (hashBytes) 
     free(hashBytes); 
    if (signedHashBytes) 
     free(signedHashBytes); 

    return signedHash; 
} 

驗證(使用SHA256與RSA):

BOOL PKCSVerifyBytesSHA256withRSA(NSData* plainData, NSData* signature, SecKeyRef publicKey) 
{ 
    size_t signedHashBytesSize = SecKeyGetBlockSize(publicKey); 
    const void* signedHashBytes = [signature bytes]; 

    size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH; 
    uint8_t* hashBytes = malloc(hashBytesSize); 
    if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], hashBytes)) { 
     return nil; 
    } 

    OSStatus status = SecKeyRawVerify(publicKey, 
             kSecPaddingPKCS1SHA256, 
             hashBytes, 
             hashBytesSize, 
             signedHashBytes, 
             signedHashBytesSize); 

    return status == errSecSuccess; 
} 

替代(OpenSSL的):

有可用的很好的替代,其直接利用,而不是libCommonCrypto OpenSSL的。 MIHCrypto是一個設計良好的用於OpenSSL的Objective-C包裝庫,它使得使用密碼非常簡單。看下面的例子。

生成密鑰就是這麼簡單:

MIHAESKeyFactory *factory = [[MIHAESKeyFactory alloc] init]; 
id<MIHSymmetricKey> aesKey = [factory generateKey]; 

或加載從文件的關鍵:

NSData *privateKeyData = [[NSFileManager defaultManager] contentsAtPath:"mykey.pem"]; 
MIHRSAPrivateKey *privateKey = [[MIHRSAPrivateKey alloc] initWithData:privateKeyData]; 

現在註冊了一句:

NSError *signingError = nil; 
NSData *message = // load something to sign from somewhere 
NSData *signature = [privateKey signWithSHA256:message error:&signingError] 

更多的例子,瀏覽MIHCrypto頁。

+1

在** Swift **中有一個類似的'SecKeyRawSign'和'SecKeyRawVerify'的例子會很棒。如果有人成功了,請鏈接到/粘貼在這裏。當我得到它的時候會做同樣的事情。 – stannie

+0

運氣好嗎?我真的需要幫助! http://stackoverflow.com/questions/32759385/swift-rsa-encrypt-a-string-with-a-specific-private-key –

+2

不要忘記導入