Получите хэш SHA1 сертификата цепочки ключей macOS в Swift

Я получил набор сертификатов в своей связке ключей, используя этот код:

    let query: [String: Any] = [
        kSecClass as String: kSecClassCertificate,
        kSecMatchLimit as String: kSecMatchLimitAll,
        kSecReturnAttributes as String: false,
        kSecReturnData as String: true
    ]

    var result: CFTypeRef?
    
    var results : Set<CertsResult> = []


    let status = SecItemCopyMatching(query as CFDictionary, &result)
    //[Check status]

    guard let certificateData = result as? [CFData] else {
        //[Handle]
    }

Отсюда я просматриваю certificateData и собираю информацию о сертификатах, но мне также нужно получить хэш SHA1 сертификатов. Из исследований я понял, что мне нужно использовать import CommonCrypto и CC_SHA1, но то, что я прочитал, не использует CFData.

Есть ли хороший способ добраться от этой точки до его SHA1?


person ZAD-Man    schedule 15.01.2021    source источник


Ответы (1)


Вы можете добиться этого, выполнив хэш самостоятельно. Отпечатки пальцев не являются частью самого сертификата. Подробнее об этом читайте здесь.

import CryptoKit

let certificate = ...

let der = SecCertificateCopyData(certificate) as Data
let sha1 = Insecure.SHA1.hash(data: der)
let sha256 = SHA256.hash(data: der)

Это также может быть создано в расширении. Я использовал CommonCrypto в расширении.

import CommonCrypto

extension SecCertificate {
    var sha1: Data {
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
        let der = SecCertificateCopyData(self) as Data
        _ = CC_SHA1(Array(der), CC_LONG(der.count), &digest)
        return Data(digest)
    }

    var sha256: Data {
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
        let der = SecCertificateCopyData(self) as Data
        _ = CC_SHA256(Array(der), CC_LONG(der.count), &digest)
        return Data(digest)
    }
}

Я хотел бы отметить, что хэши сертификатов SHA-1 устарели примерно с 2017 года, и веб-сайты и технологические гиганты начинают отказываться от их поддержки.

Пример детской площадки

import CryptoKit
import Foundation

class CertificateStuff: NSObject, URLSessionDelegate {
    func urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
    ) {
        guard let serverTrust = challenge.protectionSpace.serverTrust else {
            completionHandler(.rejectProtectionSpace, nil)
            return
        }

        for index in 0 ..< SecTrustGetCertificateCount(serverTrust) {
            let certificate = SecTrustGetCertificateAtIndex(serverTrust, index)!

            let der = SecCertificateCopyData(certificate)
            let sha1 = Insecure.SHA1.hash(data: der as Data)
            let sha256 = SHA256.hash(data: der as Data)

            print(certificate)
            print(sha1)
            print(sha256)
            print()
        }
        completionHandler(.performDefaultHandling, nil)
    }

    func request(_ done: @escaping (Result<Data, Error>) -> Void) {
        let url = URL(string: "https://security.stackexchange.com/questions/14330/what-is-the-actual-value-of-a-certificate-fingerprint")!
        let request = URLRequest(url: url)
        URLSession(configuration: .default, delegate: self, delegateQueue: nil).dataTask(with: request) { (d, r, e) in
            if let e = e {
                print(e)
                return
            }
            print(d!)
        }.resume()
    }
}

CertificateStuff().request { result in print(result) }

person Bram    schedule 18.01.2021
comment
Спасибо! И спасибо за предупреждение об устаревании SHA-1, это будет полезно в некоторых предстоящих обсуждениях. - person ZAD-Man; 20.01.2021
comment
О, классное обновление! Знаете ли вы, есть ли какие-либо способы сделать это до 10.15? Я предполагаю, что CC_SHA1 будет вовлечен... - person ZAD-Man; 21.01.2021
comment
@ ZAD-Man проверьте обновленный ответ. Я добавил обычное криптографическое расширение к объекту SecCertificate. - person Bram; 21.01.2021
comment
О, чувак, большое спасибо. Я был так близок, но я все еще новичок в Swift и не мог понять, как преобразовать данные в то, что CC_SHA1 нужно. - person ZAD-Man; 21.01.2021