Muszę podpisać żądania przed wysłaniem ich na serwer zaplecza. Jednak klucz prywatny jest mi dany. Muszę go zaimportować, a następnie użyć go do podpisania. Mogę zaimportować i zalogować się, ale dane różnią się od tych, które otrzymuję, podpisując się za pomocą openssl. Wiem, że robi to źle, ponieważ podczas importowania klucza publicznego nie mogę go również zweryfikować. Jeśli istnieje sposób, że mogę uniknąć importowania do pęku kluczy, to też byłoby świetnie. Ciężko pracowaliśmy nad tym przez kilka dni i jest to dla nas bardzo ważne zadanie. Czy ktoś może ci pomóc. Importowanie klucza prywatnego do pęku kluczy nie działa zgodnie z oczekiwaniami w telefonie iPhone
- (SecKeyRef) getPrivateKey {
//RSA KEY BELOW IS DUMMY.
key = @"-----BEGIN RSA PRIVATE KEY-----\nORtMei3ImKI2ZKI636I4+uNCwFfZv9pyJzXyfr1ZNo7iaiW7A0NjLxikNxrWpr/M\n6HD8B2j/CSjRPW3bhsgDXAx/AI1aSfJFxazjiTxx2Lk2Ke3jbhE=\n-----END RSA PRIVATE KEY-----\n";
NSString * tag = @"adpPrivateKey";
NSString *s_key = [NSString string];
NSArray *a_key = [key componentsSeparatedByString:@"\n"];
BOOL f_key = FALSE;
for (NSString *a_line in a_key) {
if ([a_line isEqualToString:@"-----BEGIN RSA PRIVATE KEY-----"]) {
f_key = TRUE;
}
else if ([a_line isEqualToString:@"-----END RSA PRIVATE KEY-----"]) {
f_key = FALSE;
}
else if (f_key) {
s_key = [s_key stringByAppendingString:a_line];
}
}
if (s_key.length == 0) return(nil);
// This will be base64 encoded, decode it.
NSData *d_key = [NSData dataFromBase64String:s_key];
if(d_key == nil) return nil;
NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
// Delete any old lingering key with the same tag
NSMutableDictionary *privateKey = [[NSMutableDictionary alloc] init];
[privateKey setObject:(id) kSecClassKey forKey:(id)kSecClass];
[privateKey setObject:(id) kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[privateKey setObject:d_tag forKey:(id)kSecAttrApplicationTag];
SecItemDelete((CFDictionaryRef)privateKey);
CFTypeRef persistKey = nil;
// Add persistent version of the key to system keychain
[privateKey setObject:d_key forKey:(id)kSecValueData];
[privateKey setObject:(id) kSecAttrKeyClassPrivate forKey:(id)
kSecAttrKeyClass];
[privateKey setObject:[NSNumber numberWithBool:YES] forKey:(id)
kSecReturnPersistentRef];
OSStatus secStatus = SecItemAdd((CFDictionaryRef)privateKey, &persistKey);
if (persistKey != nil) CFRelease(persistKey);
if ((secStatus != noErr) && (secStatus != errSecDuplicateItem)) {
[privateKey release];
return(nil);
}
// Now fetch the SecKeyRef version of the key
SecKeyRef keyRef = nil;
[privateKey removeObjectForKey:(id)kSecValueData];
[privateKey removeObjectForKey:(id)kSecReturnPersistentRef];
[privateKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef
];
[privateKey setObject:(id) kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
secStatus = SecItemCopyMatching((CFDictionaryRef)privateKey,
(CFTypeRef *)&keyRef);
if(secStatus != noErr)
return nil;
[privateKey release];
return keyRef;
}
poniższy kod służy do podpisania. Część kodu z przykładu Apple (http://developer.apple.com/library/ios/#samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_m.html#//apple_ref/doc/uid/DTS40008019-Classes_SecKeyWrapper_m-DontLinkElementID_17)
- (NSData *)getSignatureBytes:(NSString *)plainText {
OSStatus sanityCheck = noErr;
NSData * signedHash = nil;
uint8_t * signedHashBytes = NULL;
size_t signedHashBytesSize = 0;
SecKeyRef privateKey = NULL;
privateKey = [self getPrivateKey];
signedHashBytesSize = SecKeyGetBlockSize(privateKey);
//Create a SHA Encoded
NSString * shaEncoded = [self sha256:plainText];
NSLog(@"%@", shaEncoded);
// Malloc a buffer to hold signature.
signedHashBytes = malloc(signedHashBytesSize * sizeof(uint8_t));
memset((void *)signedHashBytes, 0x0, signedHashBytesSize);
NSData *inputData = [self getHashBytes:[plainText dataUsingEncoding:NSUTF8StringEncoding]];
int bytesLengthUINT8 = [inputData length];
sanityCheck = SecKeyRawSign (privateKey, kSecPaddingPKCS1, (const uint8_t *)inputData, CC_SHA256_DIGEST_LENGTH,(uint8_t *)signedHashBytes, &signedHashBytesSize);
if(sanityCheck != noErr)
return nil;
signedHash = [NSData dataWithBytes:(const void *)signedHashBytes length:(NSUInteger)signedHashBytesSize];
NSString *string = [signedHash base64EncodedString];
NSLog(@"%@", string);
if (signedHashBytes) free(signedHashBytes);
return signedHash;
}
użyłem przykładowy kod w http://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios/ importować klucz publiczny i zweryfikować i jego wadą.
Jaka jest wartość 'kSecPaddingPKCS1'? Czy możesz spróbować porównać moduły klucza publicznego i prywatnego? –
Cześć @ Owszem, proszę wyjaśnić, co robić? Czy widzisz jakiś problem w sposobie zapisywania i pobierania klucza prywatnego. Proszę dać mi znać, jeśli dostępne są inne biblioteki, których mogę użyć. –
Przepraszam, nie jestem ekspertem od ios. Trochę teraz mówię o kryptografii, więc pomyślałem, że dam ci ogólne zalecenia. Na przykład. 'kSecPaddingPKCS1' nie określa skrótu, a SHA-1 prawdopodobnie będzie domyślny. Jeśli moduł klucza prywatnego i klucza publicznego nie jest zgodny, to nie należą one do tej samej pary kluczy. W obu przypadkach weryfikacja podpisu zakończy się niepowodzeniem. –