[android] Android P 부터는 기본으로 TLS |
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>
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] Pie (9) 의 Power management (0) | 2019.07.29 |
---|---|
[android] Pie (POS) 에서의 text (0) | 2019.07.25 |
[android] POS, target SDK 28 이상의 동작 변경 (0) | 2019.07.23 |
[Android] 8.1 Feature and APIs (API Level 27) (0) | 2019.07.22 |
[android] Adoptable Storage (0) | 2019.07.09 |
댓글