본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Android P 부터는 기본으로 TLS

by 돼지왕 왕돼지 2019. 7. 24.
반응형

[android] Android P 부터는 기본으로 TLS


android p tls, android:networkSecurityConfig, application tag, ApplicationInfo.flags, base-config, best effort, certificate pinning, clearText, Configure CAs, detectCleartextNetwork, domain-config, getDefaultHostnameVerifier, manifest attribute, mos, Network Security Config, network security configuration, network security setting, networksecurityconfig, NetworkSecurityPolicy.isCleartextTrafficPermitted, NOS, pin certifictes, pre-installed ca, socket api, socket traffic, socketfactory vs sslsocketfactory, sslsocket hostname verification, strictmode cleartext, target 23, tls by default, tls fast, tls slow, Traffic, usescleartexttraffic, [android] Android P 부터는 기본으로 TLS, 신뢰할 수 있는 ca


https://android-developers.googleblog.com/2018/04/protecting-users-with-tls-by-default-in.html


android:usesCleartextTraffic 이라는 manifest attribute 가 MOS 부터 추가되었다.

NOS 에서는 Network Security Config 기능이 추가되었다.



-

모든 Connection 이 TLS 를 사용한다면 아무런 조치를 취하지 않아도 된다.



-

TLS 는 느리지 않다.



-

Socket 을 직접 만들어 사용하는 경우 SocketFactory 대신 SSLSocketFactory 를 사용해라.

SSLSocket 은 hostname verification을 하지 않기 때문에 주의해야 한다.

getDefaultHostnameVerifier() 를 통해 hostname verification 을 해야 한다.

(돼왕 : Hostname verification 은 man-in-the-middle attack 에 의해 redirect 된 것이 아닌 올바른 서버와 통신하는지를 verify 해주는 것을 이야기한다. )



-

그럼에도 cleartext connection 을 써야 한다면..

usesCleartextTraffic 나 Network Security Config 를 사용하면 된다.





usesCleartextTraffic manifest application attribute


https://developer.android.com/guide/topics/manifest/application-element


-

usesCleartextTraffic 값의 기본값은 true 이다.

false 로 설정하면 HTTP, FTP stack 과 DownloadManager, MediaPlayer 등이 cleartext traffic 을 사용하는 것을 원치 않는다는 것을 의미한다.

cleartext traffic 을 사용하지 않길 원하는 주된 이유는 보안상의 이유이다.



-

이 flag 는 best effort basis 로 작동한다.

Socket API 를 사용하는 곳에서 이 flag 를 무조건 참고하여 통신할 것이라고 확신할 순 없다.

왜냐하면 socket 은 traffic 이 cleartext 인지 아닌지 알 수 없기 때문이다.


하지만 대부분의 network traffic 은 더 높은 level 의 network stack/component 에서 작동하기 때문에 ApplicationInfo.flags 나 NetworkSecurityPolicy.isCleartextTrafficPermitted() 값을 참고하여 보안에 신경써줘야 한다.

(WebView 는 target API level 26 이상부터는 이 flag 를 따른다.)



-

StrictMode 에 StrictMode.VmPolicy.Builder.detectCleartextNetwork() 를 하면 cleartext traffic 을 감시할 수 있다.

이는 API Level 23 (MOS) 추가되었다.



-

이 flag 는 Android Network Security Config 가 존재하는 Android 7.0 (API 24, NOS) 부터 무시된다.








Security Config


https://developer.android.com/training/articles/security-config


-

Network security configuration 은 app 이 network security setting 을 code 변환 없이 설정할 수 있게 만들어준다. ( 이 말은 xml 로 control 하겠다는 말이렸다. )

이 setting 은 특정 domain 에 한정될 수 있고, 특정 app 에 한정될 수도 있다.



-

key feature 는..

    신뢰할 수 있는 CA 지정

    Secure connection debug

    Cleartext traffic allow option 지정

    특정 CA 에 한정한 connection 설정



-

manifest 의 application tag 에 android:networkSecurityConfig 에 설정 xml 을 link 해주면 된다.

<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>



** Customize Trusted CAs


다음의 이유로 특정 CA set 만 신뢰하고 싶을 수 있다.

    연결하려는 host 가 self-signed CA 라던지 회사가 발행한 CA 라던지..

    믿을 수 있는 CA 만 한정하고 싶다던지..

    system 에 없는 추가 CA 를 등록하고 싶다던지..


기본적으로 TLS, HTTPS 들은 system 에 미리 설치된 CA 들을 모두 신뢰한다.

그리고 target 23 (6.0, MOS) 이하 단말들에서는 user 가 추가한 CA 도 함께 신뢰한다.

base-config(app-wide) 나 domain-config(per domain) 안에서 이를 설정해줄 수 있다.


<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
    </domain-config>
</network-security-config>


<!— my_ca 는 self-signed 또는 non-public CA 로 PEM 이나 DER format 이면 된다. —>

System 에 의해 신뢰되지 않는 CA 도 마찬가지로 추가할 수 있다.

<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="@raw/extracas"/>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
</network-security-config>



Configure CAs for debugging


android:debuggable 이 true 일 때만 신뢰하는 debug-only CA 를 등록할 수도 있다. (개발서버는 SSL certificate 가 없을 때)

<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="@raw/debug_cas"/>
        </trust-anchors>
    </debug-overrides>
</network-security-config>



Opt out of cleartext traffic


target 27(O MR1) 이하에만 아래의 가이드가 적용된다. 28(POS) 이상부터는 기본으로 cleartext support 가 disable 되어 있다. (이 말은 cleartextTrafficPermitted 기본값이 true 였고, POS 부터 false 라는 의미렸다.)


아래와 같이 설정함으로써 특정 domain 에 대해 secure connection 만 강제할 수 있다.

<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">secure.example.com</domain>
    </domain-config>
</network-security-config>



Pin certificates


일반적으로 앱은 pre-installed CA 를 신뢰한다.

하지만 이 중 일부가 문제가 생겼을 경우 app 은 man in the middle attack 을 당할 가능성이 높아진다.

이 경우 certificate pinning 을 통해서 CA set 을 제한할 수 있다.


이는 certificates 의 public key 의 hash 를 set 으로 제공함으로 한다.


이 때 backup pin 들을 설정해 놓는 것이 좋다.

만약 새로운 key 로 변경되거나 CA 의 변경 등이 생겼을 때 다른 CA 를 이용하게 된다.

expire date 를 설정하는 것도 이 중 한 방법이다.

<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <pin-set expiration="2018-01-01">
            <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
            <!-- backup pin -->
            <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
        </pin-set>
    </domain-config>
</network-security-config>



반응형

댓글