2
在我的應用程序中,我有一個公鑰(用字符串表示),普通消息和數字簽名,用base64編碼的字符串表示,用SHA256散列並用RSA加密)。 現在,我需要驗證數字簽名。我試圖做如下:iOS驗證數字簽名
- 創建
SecKeyRef
從NSString
(從here拍攝) - 創建SHA256從原始消息
- 消化使用
SecKeyRawVerify
功能
(我想驗證簽名以避免使用OpenSSL功能)
此外,我的數字簽名是由我們創建的使用Java的SHA256withRSA方法。我正在閱讀here SHA256WithRSA將算法標識符與實際散列值相加。現在,我不確定是否需要將它附加到散列。
無論如何,在這兩種情況下,我得到的錯誤-50,根據蘋果的文件意味着一個 或更多參數傳遞給一個函數是無效的。
這裏是我的代碼:
-(BOOL) verifySignature:(NSString*) rawData andKey:(NSString*) key andSignature:(NSString*)signature {
NSData* originalData = [rawData dataUsingEncoding:NSUTF8StringEncoding];
NSData *signatureData = [NSData dataFromBase64String:signature];
SecKeyRef publicKey = [self generatePublicKey:key];
uint8_t sha2HashDigest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256([originalData bytes], [originalData length], sha2HashDigest);
//DO I NEED THIS?
NSString *algIdentifier = @"1.3.14.3.2.26";
NSData *algData = [algIdentifier dataUsingEncoding:NSUTF8StringEncoding];
NSData* d_hash = [NSData dataWithBytes:sha2HashDigest length:CC_SHA256_DIGEST_LENGTH];
NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:algData];
[concatenatedData appendData:d_hash];
OSStatus verficationResult = SecKeyRawVerify (publicKey,
kSecPaddingPKCS1SHA256,
(const uint8_t *)[d_hash bytes],
(size_t)[d_hash length],
(const uint8_t *)[signatureData bytes],
(size_t)[signatureData length]
);
CFRelease(publicKey);
if (verficationResult == errSecSuccess){
NSLog(@"Verified");
return YES;
}
return NO;
}
- (SecKeyRef)generatePublicKey:(NSString *)key
{
// This will be base64 encoded, decode it.
NSData *d_key = [NSData dataFromBase64String:key];
d_key = [self stripPublicKeyHeader:d_key];
if (d_key == nil) return(nil);
NSData *d_tag = [NSData dataWithBytes:[@"pubKey" UTF8String] length:[@"pubKey" length]];
NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];
[publicKey setObject:(id) kSecClassKey forKey:(id)kSecClass];
[publicKey setObject:(id) kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[publicKey setObject:d_tag forKey:(id)kSecAttrApplicationTag];
SecItemDelete((CFDictionaryRef)publicKey);
CFTypeRef persistKey = nil;
// Add persistent version of the key to system keychain
[publicKey setObject:d_key forKey:(id)kSecValueData];
[publicKey setObject:(id) kSecAttrKeyClassPublic forKey:(id)
kSecAttrKeyClass];
[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)
kSecReturnPersistentRef];
OSStatus secStatus = SecItemAdd((CFDictionaryRef)publicKey, &persistKey);
if (persistKey != nil) CFRelease(persistKey);
if ((secStatus != noErr) && (secStatus != errSecDuplicateItem)) {
[publicKey release];
return(nil);
}
// Now fetch the SecKeyRef version of the key
SecKeyRef keyRef = nil;
[publicKey removeObjectForKey:(id)kSecValueData];
[publicKey removeObjectForKey:(id)kSecReturnPersistentRef];
[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef
];
[publicKey setObject:(id) kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
secStatus = SecItemCopyMatching((CFDictionaryRef)publicKey,
(CFTypeRef *)&keyRef);
[publicKey release];
return keyRef;
}
在調用SecKeyRawVerify之前,您需要將算法標識符預先推送到使用CC_SHA256 – Maggie
獲取的「散列」數組。嗯,我沒有看到它在文檔中的位置。它對該論點說:「正在驗證[簽名]的數據,通常是實際數據的摘要」,因此我傳遞了實際數據的摘要(SHA256哈希)。你能詳細說明一下嗎?具體是什麼格式? – user3100783
剛通過數據爲你工作嗎?我必須在實際的散列數據上加上一個算法標識符。 id-sha256:30 0b 06 09 60 86 48 01 65 03 04 02 01 – Maggie