#iphone #ios #cryptography #public-key
#iPhone #iOS #криптография #открытый ключ
Вопрос:
Меня попросили проверить открытый ключ на соответствие известному значению в canAuthenticateAgainstProtectionSpace
(обратный вызов делегата NSURLConnection
)
Это то, что у меня есть на данный момент:
- (BOOL)connection:(NSURLConnection *)connection
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
SecKeyRef publicKey = SecTrustCopyPublicKey([protectionSpace serverTrust]);
NSLog(@"%@",SecTrustCopyPublicKey([protectionSpace serverTrust]));
return YES;
}
Как я могу сравнить открытый ключ с известным значением?
NSLog выдает: <SecKeyRef: 0x687c000>
что не очень полезно.
Ответ №1:
Если кому-то интересно, решением было проверять сертификат байт за байтом с помощью сертификата, сохраненного в пакете.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
SecTrustRef trust = [protectionSpace serverTrust];
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, 0);
NSData* ServerCertificateData = (NSData*) SecCertificateCopyData(certificate);
// Check if the certificate returned from the server is identical to the saved certificate in
// the main bundle
BOOL areCertificatesEqual = ([ServerCertificateData
isEqualToData:[MyClass getCertificate]]);
[ServerCertificateData release];
if (!areCertificatesEqual)
{
NSLog(@"Bad Certificate, canceling request");
[connection cancel];
}
// If the certificates are not equal we should not talk to the server;
return areCertificatesEqual;
}
Комментарии:
1. Отлично! Как вы сохраняете сертификат для сравнения? Или вы сравниваете только хэш-значения?
2. @joshis хранится в пакете в виде .cer-файла. Я использовал NSData dataWithContentsOfFile:.
[MyClass getCertificate]
Это метод попустительства, который возвращает сертификаты как NSData.3. … вы правы — забыли, что мы говорим здесь об открытом ключе, и нет необходимости скрывать ключ…
4. Предупреждение… Если вам даже потребуется обновить сертификат (например, если срок его действия истек), то эта проверка завершится неудачей. Я думаю, что более перспективно просто проверить домен или эмитента, не уверен, как это сделать, хотя.
5. Проверка сертификата — байт за байтом — не будет работать для Google (и др.). Google закрепляет свои открытые ключи и регулярно меняет их сертификаты. Вы должны выполнить проверку по открытому ключу.
Ответ №2:
Обратите внимание, что SecCertificateCopyData возвращает сертификат в форме «DER», отличающейся правилами кодирования. Итак, вам нужно включить сертификат в ваше приложение в этой форме, а не в виде pem или любого другого формата. Чтобы преобразовать сертификат в DER с помощью openssl, используйте команду: openssl x509 -in server.crt -out server.der -outform DER
Комментарии:
1. Просто информация, которая мне была нужна — Спасибо!