iOS에서 CRL 및 OSCP 확인을 작동시키는 방법은 무엇입니까?


9

iOS에서 CRL을 작동시킬 수 없습니다. 두 가지 테스트 사례를 만들었습니다. CA에서 발급 한 유효한 인증서가 있습니다. CA에서 발급 한 유효한 다른 인증서가 있지만 CA가 해당 인증서를 CRL에 추가했습니다.

그런 다음 CRL 검사를 활성화하는 취소 정책을 설정하고 성공해야합니다.

func crlValidationTest(trustedCert: SecCertificate, certToVerify: SecCertificate) -> Bool {

    let basicPolicy = SecPolicyCreateBasicX509()

    let crlPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod | kSecRevocationCRLMethod | kSecRevocationRequirePositiveResponse)!

    var trust: SecTrust?

    SecTrustCreateWithCertificates(NSArray(object: certToVerify), NSArray(objects: basicPolicy, crlPolicy), &trust)
    SecTrustSetAnchorCertificates(trust!, NSArray(object: trustedCert))
    SecTrustSetNetworkFetchAllowed(trust!, true)

    var trustResult = SecTrustResultType.invalid

    guard SecTrustEvaluate(trust!, &trustResult) == errSecSuccess else {
        return false
    }

    return trustResult == SecTrustResultType.proceed || trustResult == SecTrustResultType.unspecified
}

CRL에있는 인증서는 신뢰할 수없고 깨끗한 인증서는 신뢰할 것으로 기대합니다.

위의 구성으로 인해 둘 다 신뢰할 수없는 것으로 실패합니다. kSecRevocationRequirePositiveResponse플래그를 제거하면 둘 다 성공합니다. OSCP 또는 CRL 만 사용하는 다른 모든 순열을 시도했지만 예상대로 작동하지 않습니다.

상태에 대한 Apple 문서SecPolicyCreateRevocation :

특정 방법을 강요하거나 해지 확인을 완전히 비활성화하기 위해 기본 시스템 동작을 무시하지 않는 한 일반적으로 해지 정책을 직접 만들 필요는 없습니다.

SecPolicyCreateBasicX509정책 만 사용 하면 두 가지 모두 성공할 수 있습니다 (두 번째 인증서가 실패 할 때) .CRL 검사를 전혀하지 않는 Apple의 기본 동작입니까?

나는 부착 CharlesProxy를 내 장치, 모든 네트워크 트래픽을 들으면서 코드를 여러 번 실행하고, 더 아웃 바운드 요청은 이제까지 때 모든 실패 이유를 설명 CRL에 갈 RequirePositiveResponse플래그가 확인됩니다.

또한를 사용하여 장치에서 CRL로 직접 탐색하려고 시도했지만 URLRequest아무런 문제없이 장치에서 CRL 데이터를 얻을 수있었습니다.

Apple Security 라이브러리를 통해 CRL 검사가 지원되지 않습니까? 그렇다면 올바르게 응답하도록 구성을 알아 낸 사람이 있습니까? CRL 유효성 검사를 수행하기 위해 어떤 대안을 사용하고 있습니까? 나는 금융 지구 또는 기타 민감한 지역에서 다루는 높은 보안 모바일 응용 프로그램 이이 적용 범위 차이를 허용하지 않을 것이라고 가정합니다.

업데이트 비교를 위해certutil -f -urlfetch -verify MYCERT.cercertutil을 사용하여 명령을 실행하는 상자에 Fiddler 를첨부했습니다. iOS에서 제공하지 않는 예상 결과를 수신하고 피들러를 통해 HTTP를 통해 CRL에 대한 아웃 바운드 요청을 봅니다.

나는 이것에 더 많은 관심을 불러 일으키는 현상금을 만들었습니다. 위의 문제가 무엇인지, 왜 iOS에서 작동하지 않는지에 대한 자세한 내용을 누군가가 원합니다.

답변:


7

Apple 플랫폼에서 클라이언트는 CA의 CRL (Certificate Revocation List)을 확인하거나 기본적으로 OCSP를 사용하지 않습니다.

그러나 Apple 플랫폼은 OCSP 스테이플 링을 지원하고 대안 적으로 OCSP 호출로 이어질 수있는 해지 향상 (Revocation Enhancement)이라는 메커니즘을 제공합니다 (아래 세부 사항 참조).

OCSP 스테이플 링

먼저 OCSP 스테이플 링에 대한 설명 :

온라인 인증서 상태 프로토콜 (OCSP) 스테이플 공식적으로 알려진 TLS 인증서 상태 요청 확장은 X.509 디지털 인증서의 해지 상태를 확인하기위한 표준이다. 1 인증서 발표자는 CA가 서명 한 타임 스탬프 된 OCSP 응답을 초기 TLS 핸드 셰이크에 추가 ( "스테이플 링")하여 OCSP (Online Certificate Status Protocol) 응답 제공과 관련된 리소스 비용을 부담 할 필요가 없습니다. 보안 및 성능 향상을 목표로 클라이언트가 CA에 문의 할 수 있습니다.

참조 https://en.wikipedia.org/wiki/OCSP_stapling를

OCSP와 OCSP 스테이플 링의 차이점

클라이언트가 기존의 OCSP 플로우에서 서버에 연결하고 인증서를 검색하는 경우 CA에 요청하여 수신 된 인증서가 해지되었는지 확인합니다. 예를 들어, 추가 네트워크 연결이 필요하고 정보가 암호화되지 않아 데이터 프라이버시 문제를 나타내는 등 몇 가지 단점이 있습니다.

OCSP 스테이플 링을 통해 서버는 CA에 서명 된 해지 정보를 요청하고이를 TLS 핸드 셰이크에 추가합니다.

이는 또한 OCSP 스테이플 링을 사용할 때 iOS에서 CA 서버로의 OCSP 요청이 표시되지 않음을 의미합니다.

OCSP 스테이플 링의 단점

연결중인 서버는 OCSP 스테이플 링을 지원해야합니다. 또한 악의적 인 서버로부터 보호되지 않습니다.

이것이 Apple이 해지 강화를 제공하는 주된 이유입니다.

애플의 해지 향상

작동 방식은 다음과 같습니다.

  • 인증서 투명성 로그 항목은 Apple에서 수집합니다.
  • 이 정보로 Apple은 CA의 해지에 관한 정보를 수집합니다.
  • 이렇게 집계 된 정보는 모든 Apple 클라이언트가 정기적으로 자동으로 사용할 수있게됩니다.
  • 이 정보를 기반으로 iOS 앱이 해지 된 인증서로 서버에 연결하려고하면 OCSP를 통해 추가 확인을 수행합니다.

요구 사항

앱이이를 지원하기위한 유일한 요구 사항은 사용 된 서버 인증서가 인증서 투명성 로그에 추가되어야한다는 것입니다. 일반적으로 CA는 이미이를 수행하지만 도메인 링크가 공개 인증서의 활성 투명성 로그에 있는지 확인해야합니다 (예 : https://transparencyreport.google.com/https/certificates).

WWDC 2017, 세션 701

이 주제와 Apple의 동기에 대해 자세히 설명하는 훌륭한 WWDC 세션이 있습니다 : WWDC 2017, 세션 701 : https://developer.apple.com/videos/play/wwdc2017/701/

약 12:10 분에 Apple 엔지니어가 전체 취소 주제를 자세히 설명합니다. 약 15:30에 그녀는 정상적인 OCSP가 추가 API를 사용해야한다고 설명합니다.

iOS에서 OCSP 스테이플 링 테스트

테스트를 위해 OCSP 스테이플 링을 지원하고 해지 된 인증서를 사용하는 서버가 필요합니다 : https://revoked.grc.com (이 서버에서이 서버를 찾았습니다 : https://serverfault.com/a/645066 )

그런 다음 HTML 응답을 다운로드하여 콘솔에 출력하는 작은 테스트 프로그램으로 iOS에서 연결을 시도 할 수 있습니다.

위에서 언급 한 WWDC 세션의 정보에 따라 연결 시도가 실패해야합니다.

...
let session = URLSession(configuration: .default)
...

func onDownloadAction() {
    let url = URL(string: "https://revoked.grc.com")!
    self.download(from: url) { (result, error) in
        if let result = result {
            print("result: " + result)
        } else {
            print("download failed")
            if let error = error {
                print("error: \(error)")
            }
        }
    }
}


func download(from url: URL, completion: @escaping(String?, Error?)->Void) {
    let dataTask = self.session.dataTask(with: url) { data, response, error in
        guard let data = data else {
            if let error = error {
                completion(nil, error)
                return
            }
            completion(nil, NSError(domain: "DownloadFailure", code: 0, userInfo:nil))
            return
        }

        guard let response = response as? HTTPURLResponse else {
            completion(nil, NSError(domain: "ResponseFailure", code: 0, userInfo:nil))
            return
        }
        print("http status: \(response.statusCode)")
        let res = String(bytes: data, encoding: .utf8)
        completion(res, nil)
    }
    dataTask.resume()
}

iOS 시뮬레이터에서 위의 루틴을 실행하면 Wireshark를 사용하여 CA가 서명 한 타임 스탬프 된 OCSP 응답이 TLS 핸드 셰이크에 스테이플 링되어 있는지 확인할 수 있습니다.

nslookup revoked.grc.com우리 서버의 IP 주소를 얻을과 와이어 샤크에서 필터링 할 수 있습니다 ip.addr==4.79.142.205.

스크린 샷에서 인증서가 상태임을 알 수 있습니다 revoked.

Wireshark

따라서 Xcodes 콘솔을 살펴보면 다음과 같은 출력을 볼 수 있습니다.

2019-10-12 21:32:25.734382+0200 OCSPTests[6701:156558] ATS failed system trust
2019-10-12 21:32:25.734526+0200 OCSPTests[6701:156558] Connection 1: system TLS Trust evaluation failed(-9802)
2019-10-12 21:32:25.734701+0200 OCSPTests[6701:156558] Connection 1: TLS Trust encountered error 3:-9802
2019-10-12 21:32:25.734787+0200 OCSPTests[6701:156558] Connection 1: encountered error(3:-9802)
2019-10-12 21:32:25.737672+0200 OCSPTests[6701:156558] Task <12408947-689F-4537-9642-C8F95E86CA62>.<1> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
download failed
error: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000037f8510>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
    "<cert(0x7fda78828200) s: revoked.grc.com i: DigiCert SHA2 Secure Server CA>",
    "<cert(0x7fda7882b200) s: DigiCert SHA2 Secure Server CA i: DigiCert Global Root CA>"
), NSUnderlyingError=0x600000be9170 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000037f8510>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
    "<cert(0x7fda78828200) s: revoked.grc.com i: DigiCert SHA2 Secure Server CA>",
    "<cert(0x7fda7882b200) s: DigiCert SHA2 Secure Server CA i: DigiCert Global Root CA>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://revoked.grc.com/, NSErrorFailingURLStringKey=https://revoked.grc.com/, NSErrorClientCertificateStateKey=0}

iOS는 TLS 오류로 서버에 대한 연결 시도를 중단합니다.

테스트 해지 .badssl.com

revoked.badssl.com은 OCSP 스테이플 링을 지원하지 않습니다.

https://revoked.badssl.com 의 인증서 세부 정보를 살펴보면 다음을 확인할 수 있습니다.

.crl 파일 (2.5MB)을 다운로드하여

openssl crl -inform DER -text -in ssca-sha2-g6.crl | grep 0371B58A86F6CE9C3ECB7BF42F9208FC

이 인증서가 CRL을 통해 해지되었음을 알 수 있습니다.

흥미롭게도 Safari, Chrome 또는 iOS는이 취소 상태를 인식하지 못합니다. Mozilla Firefox 만 오류 메시지를 표시합니다 ( 피어의 인증서가 취소되었습니다. 오류 코드 : SEC_ERROR_REVOKED_CERTIFICATE ).

그 이유는 인증서가 며칠 전에 갱신되었으므로 아직 모든 로컬 취소 브라우저 및 운영 체제 목록에서 그 방법을 찾지 못했기 때문일 수 있습니다.


여기에 좋은 정보가 있습니다. 신중한 답변에 감사드립니다. 이 주제를 계속 연구 해 보았 듯이 CRL 지원은 주요 브라우저 / OS에 의해 중단되고 OCSP 스테이플 링은 새로운 권장 보안 메커니즘 인 것으로 보입니다. WWDC 비디오에서 Apple 담당자는 "안타깝게도 현재 플랫폼에서 기본적으로 해지를 확인하지 않습니다"라고 말합니다. 내가 실험을 통해 찾은 것은 기본적으로 지원되지 않을뿐 아니라 (설정을 강제로 설정하더라도) 전혀 지원되지 않는다는 것입니다. @Stephan Schlecht
Unome
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.