요청을 백엔드 서버로 보내기 전에 서명해야합니다. 그러나 개인 키가 나에게 주어집니다. 그래서 그것을 가져 와서 서명에 사용해야합니다. 가져 오기 및 로그인이 가능하지만 그 데이터는 openssl을 사용하여 서명 한 것과 다릅니다. 공개 키를 가져올 때도 확인할 수 없기 때문에 잘못된 것으로 알고 있습니다. 키 체인으로 가져 오는 것을 피할 수있는 방법이 있다면, 너무 좋을 것입니다. 며칠 동안 열심히 일해 왔으며 이것은 우리를위한 대단한 일입니다. 어떤 사람이 도와 줄 수 있니? 키 체인으로 개인 키를 가져 오는 것이 예상대로 작동하지 않습니다.
- (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;
}
아래의 코드에 서명하는 데 사용됩니다. 코드의 일부는 내가 공개 키를 가져 와서 확인하고 실패 할 http://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios/의 코드 샘플을 사용하는 애플의 예 (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;
}
에서입니다.
'kSecPaddingPKCS1'의 값은 무엇입니까? 공개 키와 개인 키의 모듈 수를 비교해 볼 수 있습니까? –
안녕하세요, 제발 어떻게 해야할지 자세히 설명해 주실 수 있습니까? 또한 개인 키를 저장하고 검색하는 방식에 문제가 있는지 확인하십시오. 제가 사용할 수있는 다른 라이브러리가 있다면 알려주십시오. –
죄송합니다, 저는 전문가가 아닙니다. 이제는 암호화에 대해 꽤 많이 할 것이므로, 나는 당신에게 몇 가지 일반적인 권고안을 줄 것이라고 생각했다. 예 : 'kSecPaddingPKCS1'는 해시를 지정하지 않고 SHA-1이 기본값이 될 것입니다. 개인 키와 공개 키의 모듈러스가 일치하지 않으면 동일한 키 쌍에 속하지 않습니다. 두 경우 모두 서명 확인이 실패합니다. –