Проверка открытого ключа в canAuthenticateAgainstProtectionSpace

#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. Просто информация, которая мне была нужна — Спасибо!