Swift 네트워크 보안 원리 및 실천

5155 단어

원리 부분


대칭 암호화


대칭 키가 존재하고 정보는 대칭 키로 암호화되며 대칭 키로 복호화됩니다.

비대칭 암호화


공개 키와 개인 키가 존재합니다. 공개 키로 암호화할 수도 있고, 개인 키로 암호화할 수도 있습니다.

해시 알고리즘


클라이언트는 전송된 내용 해시를 디지털 요약을 받아 내용과 함께 서버에 보내고 서버는 받은 내용 해시를 받은 디지털 요약과 비교하면 내용이 완전무결하다.

HTTPS 원리


HTTPS = HTTP + SSL SSL 프로토콜은 클라이언트와 서버 간에 정보를 안전하게 전송하는 방법을 규정합니다.
SSL 프로토콜에서는 일반적으로 전송 키를 먼저 사용하고 키를 사용하여 통신 내용을 전송합니다. 간단하고 빠르기 때문에
1단계: 클라이언트가 SSL 세션을 요청합니다.두 번째 단계: 서버는 자신의 인증서(이 인증서가 믿을 만하다고 가정)를 클라이언트에게 보내고 그 안에 서버의 공개 키가 있습니다.3단계: 클라이언트는 의 키(일반적으로 master_secret)를 서버의 공개 키로 암호화하여pre_를 생성한다master_secret, 서버에 돌려보냅니다.4단계: 서버가 자신의 개인 키로 복호화 pre_master_secret, 마스터 획득_secret. 5단계 이후: 클라이언트가 통신 내용 및 디지털 요약을 master_secret 암호화 후 서버 발송, 서버용 master_secret 복호화, 내용 얻기, 완전성 검증.반대로도 성립된다.

Charles 및 Wireshark HTTPS 제거 방법


Charles


간단하게 말하자면, 중개인이 공격한다.위의 두 번째 단계에서 클라이언트가 받은 것은 서버의 인증서가 아니라 Charles의 것입니다. 클라이언트가 이 인증서를 신뢰하면 master_Secret은 Charles의 공개 키로 암호화하기 때문에 Charles는 master_secret, 자연히 당신들이 보낸 내용을 복호화할 수 있습니다.GG 방지 방법: 클라이언트에 자신의 서버에 인증서를 저장하고 두 번째 단계에서 인증서를 받을 때 비교한다.

Wireshark 및 Ethereal


먼저 서버의 키를 Wireshark에 알려주세요. 네 번째, Wireshark는 서버의 키로 암호화pre_master_secret, 마스터 획득_secret, 당신들이 보낸 내용을 복호화할 수 있습니다.GG 방지 방법: 서버의 개인 키를 잘 보관하세요.

실천 부분


HTTP는 명문으로 전송됩니다. 만약 당신이 HTTPS를 사용하지 않고 스스로 암호화하지 않고 HTTP로 계정 비밀번호를 전송한다면 당신은 끝장날 것입니다.iOS9은 기본적으로 HTTP를 금지합니다. 만약 당신이 반드시 사용해도 됩니다. 자체적으로 구글에서 방법을 설정합니다.의심할 여지없이 당신은 HTTPS를 사용해야 하지만 HTTPS에 올라가면 절대 안전합니까? 아니요, HTTPS는 중간자의 공격을 막을 수 없습니다.실천 부분에서 Swift+Alamofire 조건에서 인증서를 통해 중개인의 공격을 어떻게 방지하는지 말씀드리겠습니다.이 부분에 대응하는 원리는 바로 위의 이 말이다.
클라이언트에 자신의 서버 인증서를 저장하고 두 번째 단계에서 인증서를 받을 때 비교합니다.
Alamofire는 너무 잘 봉인되어 있습니다. 일반적인 요청은 이 한마디만 하면 됩니다.
Alamofire.request(.GET, "https://api.douban.com/v2/book/1220562")

리퀘스트를 누르면 리퀘스트를 실행하는 것은 Alamofire의sharedInstance입니다.불행하게도 이shared Instance의 Server Trust Policy를 수정하는 것은 쉬운 일이 아니기 때문에 관리자를 만들어야 합니다.당신의 구조에 네트워크 층이라는 것이 있기를 바랍니다. 즉, Networking Manager와 유사한 종류입니다. 만약 없다면 저의 이 글을 보십시오. 단독 네트워크 층이 없는 것은 좋은 일이 아닙니다.자, 만약에 네가 Networking Manager라는 클래스가 있다면 이 클래스의 구조는 내가 위에 쓴 글에 따라 구성된다. 이 클래스는 하나의 예가 있고 모든 API는 하나의 실례적인 방법에 대응한다.
var manager: Manager?

Networking Manager 클래스에서 이러한 변수를 정의합니다. Manager는 Alamofire의 관리 클래스입니다.이러한 초기화 방법을 추가하거나 초기화 방법에 다음과 같은 내용을 추가합니다.
init() {
        let serverTrustPolicy = ServerTrustPolicy.PinCertificates(
            certificates: ServerTrustPolicy.certificatesInBundle(),
            validateCertificateChain: true,
            validateHost: true
        )
        
        let serverTrustPolicies: [String : ServerTrustPolicy] = ["api.douban.com":serverTrustPolicy]
        
        manager = Manager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
    }

여기서 질문이 하나 있습니다. 먼저 그 뜻을 말씀드리자면 ServerTrustPolicy는 Alamofire에서 서버 검증을 관리하는 클래스로 다음과 같은 몇 가지 검증 방법을 제공합니다.
  • PerformDefault Evaluation 즉 기본값입니다. 시도하지 않았기 때문에 이 기본값이 안전한지 모르겠습니다..
  • PinCertificates 인증서, 즉 내가 사용하는 방법
  • PinPublicKeys 인증 공개 키
  • DisableEvaluation 비검증, 정말 큰 마음...
  • Custom Evaluation DIY 검증, 6가 되면 이것을 선택할 수 있습니다
  • certificates InBundle 즉 당신이 Bundle에 넣은 인증서입니다. Alamofire는 이 인증서를 앞의 두 번째 서버에서 전송된 인증서와 비교합니다. 만약 통신을 거절하지 않으면 Charles 같은 중개인의 공격도 틈이 없습니다.
    어떻게 인증서를 Bundle에 넣습니까?끌고 들어가서 copy If Needed와 아래의 Target을 선택하십시오.테스트를 하려면 인증서를 어디서 찾습니까?예컨대https://api.douban.com/v2/book/1220562이런 HTTPS 사이트는 브라우저로 열면 주소 표시줄 왼쪽에 작은 자물쇠가 있습니다. 들어가서 찾아보세요. 마지막으로 인증서를 찾아서 데스크톱으로 드래그하면 접두사가 될 수 있습니다.cer 같은 거.
    서버 Trust Policy, 즉 검증 전략을 얻었습니다. 여기는 인증서로 검증하는 전략입니다.Alamofire 또는 iOS는 서로 다른 호스트에 대해 서로 다른 검증 정책을 실행할 수 있도록 합니다. 이 대응 관계는 [String: Server Trust Policy] 같은 사전에 놓여 있습니다. 왼쪽은 host(전체 URL이 아닙니다), 오른쪽은 policy, 즉 위의 Server Trust Policies입니다. 이것을 가지고 Server Trust Policy 관리자를 생성하고 관리자의 초기화 방법을 이용하여 관리자에게 값을 부여합니다.
    URL의 호스트가 어떤 부분인지 어떻게 알아요?좋은 방법이 있습니다. playground를 열고 전체 URL 문자열로 NSURL을 만들고 이 NSURL 실례host를 가져와서 오른쪽으로 되돌아오는 값을 보십시오.
    그리고 안전한 관리자를 설정한 실례가 있습니다.
    테스트를 위해 네트워크 층 관리 클래스에 테스트 함수를 썼습니다. 이 안전한 관리자로 리퀘스트를 사용합니다.
    func testSSL() {
        manager!.request(.GET, "https://api.douban.com/v2/book/1220562").responseJSON(options: .AllowFragments) { (response) in
            guard let json = response.result.value else {
                print("\(response.result.error)")
                return
            }
            print(json)
        }
    }
    

    그리고 메인 VC에서 이렇게 호출합니다.
    NetworkingManager.sharedInstance.testSSL()
    

    인증서 설정이 정확해야만 json을 얻을 수 있습니다. 인증서를 넣지 않았거나 맞추지 않았더라면 출력 오류가 발생했습니다.만약 인증서가 맞지 않는다면, 즉 Alamofire는 서버가 준 인증서가 틀렸다고 생각하고 서버와의 통신을 거절합니다.
    위에서 언급한 문제는 왜 반드시 Networking Manager 클래스에 관리자 변수를 설정하고 테스트 SSL에서 정의해야 하는지입니다. 정의를 다 하면 안 됩니까?답은 안 돼요. 계속 가지고 있어야 해요. 일단 Alamofire가 인터넷 요청을 처리하러 가면 정의된 관리자가 풀려요. 관리자가 풀려나면 요청이 자연히 취소되기 때문에 json을 받을 수 없어요.통상적으로 Alamofire를 사용하기 때문이다.sharedInstance, 그것은 줄곧 존재하기 때문에 일반적으로 이 문제를 느끼지 못한다.
    마이크로박: @ 나는 웃는다_NSNirvana는 개인 편지를 환영합니다.

    좋은 웹페이지 즐겨찾기