Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
HTTPSの基本から NetworkSecurityConfigまで
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Amane Nikaido
February 09, 2018
Technology
4.5k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
HTTPSの基本から NetworkSecurityConfigまで
Amane Nikaido
February 09, 2018
More Decks by Amane Nikaido
See All by Amane Nikaido
React with Kotlin
a2kaido
2
1.3k
Use Kotlin for build.gradle.
a2kaido
0
500
JavaからみたKotlin
a2kaido
0
140
Other Decks in Technology
See All in Technology
アンオフィシャルな、オフィシャルからのお願い
wyamazak_devrel
0
120
マルチアカウント環境での コーディングエージェントを使った障害調査が大変なので AIエージェントにReadOnly権限を付与してみた / ReadOnly AI Agents for Multi-Account AWS Incident Response
yamaguchitk333
2
110
Socrates × Looker 〜セマンティックレイヤーで進化するデータ分析エージェント〜
hanon52_
3
2.4k
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
1.1k
LLMにもCAP定理があるという話
harukasakihara
0
390
データサイエンスを価値につなげるプロジェクト設計 〜 DS一年目が現場で得た気づき 〜
ysd113
1
260
あなたの知らないPDFのアクセシビリティ
lycorptech_jp
PRO
0
200
RAG を使わないという選択肢
tatsutaka
1
250
FinOps × AIエージェントで実現する コストインシデントの自動調査
oasis1994liveforever
0
150
On-behalf-of Token exchange with AgentCore Identity
hironobuiga
2
230
LayerXにおけるセキュリティ管理の現在地と次の一手
tosho
0
220
MCP Appsを作ってみよう
iwamot
PRO
4
670
Featured
See All Featured
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
300
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
A Soul's Torment
seathinner
6
2.9k
What's in a price? How to price your products and services
michaelherold
247
13k
A designer walks into a library…
pauljervisheath
211
24k
Color Theory Basics | Prateek | Gurzu
gurzu
0
360
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
140
Six Lessons from altMBA
skipperchong
29
4.3k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Design in an AI World
tapps
1
240
Transcript
%SPJE,BJHJ )5514ͷجຊ͔Β /FUXPSL4FDVSJUZ$POpH·Ͱ ೋ֊ಊ ว (Amane Nikaido) @a2kaido
ࣗݾհ • ௨৴͕͖Ͱ͢ • conbu͞Μͷ͓ख͍Λ ͠·ͨ͠
ຊηογϣϯͷத • HTTPS௨৴ͷׂͱΈ • NetworkSecurityConfigʹ͍ͭͯ • NΑΓલͷPinning Certificates • Pinning
Certificatesͷӡ༻
എܠ • ެऺແઢLANʹଓ͢Δػձͷ૿Ճ • ௨৴༰ͷ౪ௌվ᜵ͷՄೳੑ͕͋Δ
2014 SSLূ໌ॻݕূͷҙשى
2016 HTTPSͷεεϝ • Protecting against unintentional regressions to cleartext traffic
in your Android apps https://android-developers.googleblog.com/2016/04/protecting-against-unintentional.html • Mythbusting HTTPS: Squashing security’s urban legends - Google I/O 2016 https://www.youtube.com/watch?v=YMfW1bfyGSY
2017 Android Developers Blog • 2018/11·ͰʹTarget API levelΛ26Ҏ্ʹ ͠·͠ΐ͏ •
Android N͔ΒϢʔβʔ͕Πϯετʔϧ ͨ͠ϧʔτূ໌ॻΛ৴པ͠ͳ͍Α͏ʹ https://android-developers.googleblog.com/2017/12/improving-app-security-and- performance.html
https://goo.gl/n4Aahh
Androidͷ Ξοϓσʔτ
Android M • usesCleartextTraffic • ฏจͰͷ௨৴Λېࢭ͢Δઃఆ <application … android:usesCleartextTraffic=“false”>
… </application>
Android N • Ϣʔβ͕Πϯετʔϧͨ͠ϧʔτূ໌ॻ Λ৴པ͠ͳ͍ • NetworkSecurityConfig • ฏจͰͷ௨৴ͷࢭ •
CAͷΞϯΧʔ • Pinning Certificates(ϐϯཹΊ)
ͦͦHTTPSͱ
҉߸Խ௨৴ͷࡾཁૉ • ػີੑ • ϝοηʔδશੑ • ΤϯυϙΠϯτਅਖ਼ੑ
҉߸Խ௨৴ͷࡾཁૉ • ػີੑ • ϝοηʔδશੑ • ΤϯυϙΠϯτਅਖ਼ੑ ҉߸Խ͞Ε͍ͯͯ ౪ௌ͞Εͳ͍͜ͱ
҉߸Խ௨৴ͷࡾཁૉ • ػີੑ • ϝοηʔδશੑ • ΤϯυϙΠϯτਅਖ਼ੑ վ͟Μ͕ͳ͘ શͰ͋Δ͜ͱ
҉߸Խ௨৴ͷࡾཁૉ • ػີੑ • ϝοηʔδશੑ • ΤϯυϙΠϯτਅਖ਼ੑ ਖ਼͍͠௨৴ઌͱ ௨৴͍ͯ͠Δ͜ͱ
҉߸Խ௨৴ͷࡾཁૉ • ػີੑ • ϝοηʔδશੑ • ΤϯυϙΠϯτਅਖ਼ੑ HTTPSͰ҆શੑ͕୲อ͞Ε͍ͯΔͣͰʁ
HTTPS௨৴Λ͢ΔͨΊͷ ূ໌ॻͷ
Client Server
Client Server ΄Μͱʹਖ਼͍͠௨৴૬खͳͷ͔ͳʁ
Client Server ΄Μͱʹਖ਼͍͠௨৴૬खͳͷ͔ͳʁ Certification Authority(ೝূہ)
Client Server Certification Authority(ೝূہ) ϧʔτূ໌ॻ
Client Server Certification Authority(ೝূہ) ϧʔτূ໌ॻ ॺ໊͖ SSLূ໌ॻൃߦ
Client Server Certification Authority(ೝূہ) ϧʔτূ໌ॻ ॺ໊͖ SSLূ໌ॻൃߦ SSLূ໌ॻ
Client Server Certification Authority(ೝূہ) ϧʔτূ໌ॻ ॺ໊͖ SSLূ໌ॻൃߦ SSLূ໌ॻ CAͷॺ໊͕͋Δ͔Β ؒҧ͍ͳ͍
HTTPS௨৴ͷ ϋϯυγΣΠΫ
HTTPS௨৴ͷྲྀΕ 1/4 ClientHello Client Server
HTTPS௨৴ͷྲྀΕ 2/4 ClientHello Client Server ServerHello Certificate
HTTPS௨৴ͷྲྀΕ 2/4 ClientHello Client Server ServerHello Certificate ূ໌ॻΛνΣοΫ ৴པ͢ΔCAͷॺ໊͕͋Δ͔
HTTPS௨৴ͷྲྀΕ 3/4 ClientHello Client Server ServerHello Certificate Finish Finish
HTTPS௨৴ͷྲྀΕ 4/4 ClientHello Client Server ServerHello Certificate Finish Finish HTTPS
தؒऀ߈ܸ Client Server
தؒऀ߈ܸ ClientHello Client Server ClientHello ਖ਼͍͠ূ໌ॻ
தؒऀ߈ܸ ClientHello Client Server ClientHello ਖ਼͍͠ূ໌ॻ ূ໌ॻΛࠩ͠ସ͑
தؒऀ߈ܸ ClientHello Client Server ClientHello ਖ਼͍͠ূ໌ॻ ِͷূ໌ॻ
தؒऀ߈ܸ ClientHello Client Server ClientHello ਖ਼͍͠ূ໌ॻ ِͷূ໌ॻ Finish Finish Finish
Finish HTTPS HTTPS
தؒऀ߈ܸ ClientHello Client Server ClientHello ਖ਼͍͠ূ໌ॻ ِͷূ໌ॻ Finish Finish Finish
Finish HTTPS HTTPS ͜͜Ͱূ໌ॻͷݕূΛ ͍ͯ͠ΔͷͰʁ
ِͷূ໌ॻΛ৴པʁ • ߈ܸऀΛCAͱͯ͠৴པ͍ͯ͠Δ (ϧʔτূ໌ॻΛΠϯετʔϧ͍ͯ͠Δ) Մೳੑ • ߈ܸऀ͕CA͔Βॺ໊͖ূ໌ॻΛ औಘͨ͠Մೳੑ
ِͷূ໌ॻΛ৴པʁ • ߈ܸऀΛCAͱͯ͠৴པ͍ͯ͠Δ (ϧʔτূ໌ॻΛΠϯετʔϧ͍ͯ͠Δ) Մೳੑ • ߈ܸऀ͕CA͔Βॺ໊͖ূ໌ॻΛ औಘͨ͠Մೳੑ ৴པ͢ΔCAΛ੍ݶ͢Ε͛Δ
ِͷূ໌ॻΛ৴པʁ • ߈ܸऀΛCAͱͯ͠৴པ͍ͯ͠Δ (ϧʔτূ໌ॻΛΠϯετʔϧ͍ͯ͠Δ) Մೳੑ • ߈ܸऀ͕CA͔Βॺ໊͖ূ໌ॻΛ औಘͨ͠Մೳੑ αʔό͕ฦ٫͢Δਖ਼͍͠ূ໌ॻΛ ͋Β͔͡Ί͍ͬͯΕ͛Δ
Android N • Ϣʔβ͕Πϯετʔϧͨ͠ϧʔτূ໌ॻ Λ৴པ͠ͳ͍ • NetworkSecurityConfig • ฏจͰͷ௨৴ͷࢭ •
CAͷΞϯΧʔ • Pinning Certificates(ϐϯཹΊ)
NetworkSecurityConfig (Android NҎ߱)
NetworkSecurityConfig • ฏจͰͷ௨৴ͷࢭ • CAͷΞϯΧʔ • Pinning Certificates(ϐϯཹΊ)
ઃఆํ๏ • res/xml/network_security_config.xml • ઃఆ༰Λهड़ • AndroidManifest.xml <application …
android:networkSecurityConfig="@xml/network_security_config"> … </application>
ฏจͰͷ௨৴ͷࢭ <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </network-security-config>
CAͷΞϯΧʔ <network-security-config> <domain-config> <domain includeSubdomains="true">secure.example.com</domain> <domain includeSubdomains="true">cdn.example.com</domain> <trust-anchors> <certificates src="@raw/trusted_roots"/>
</trust-anchors> </domain-config> </network-security-config>
Pinning Certificates (ϐϯཹΊ) <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin
digest=“SHA-256”>{ hash value }</pin> <!-- backup pin --> <pin digest=“SHA-256”>{ hash value }</pin> </pin-set> </domain-config> </network-security-config>
Pinning Certificates <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest=“SHA-256”>{
hash value }</pin> <!-- backup pin --> <pin digest=“SHA-256”>{ hash value }</pin> </pin-set> </domain-config> </network-security-config> PinningͷظݶΛઃఆՄೳ ͷγεςϜ࣌ؒͱͷൺֱ
Pinning Certificates <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest=“SHA-256”>{
hash value }</pin> <!-- backup pin --> <pin digest=“SHA-256”>{ hash value }</pin> </pin-set> </domain-config> </network-security-config> αʔόʔͷSSLূ໌ॻͷϋογϡΛઃఆ
Pinning Certificates <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest=“SHA-256”>{
hash value }</pin> <!-- backup pin --> <pin digest=“SHA-256”>{ hash value }</pin> </pin-set> </domain-config> </network-security-config> base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)
digestͷ࡞Γํ (खݩͷূ໌ॻͰ) ιʔε: https://github.com/datatheorem/TrustKit/blob/master/ get_pin_from_certificate.py $ python get_pin_from_certificate.py ca.pem
digestͷ࡞Γํ (αʔόʔ͔Β) $ openssl s_client \ -connect <hostname>:<port> \ |
openssl x509 -pubkey -noout \ | openssl rsa -pubin -outform der \ | openssl dgst -sha256 -binary \ | openssl enc -base64
NetworkSecurityConfig ͷιʔείʔυͷ༠͍
ؾ࣋ͪ • ͳʹ͔͋ͬͨ࣌ʹௐ͍ࠪ͢͠ • ؾʹͳΔڍಈΛ֬ೝͰ͖ΔΑ͏ʹͳΔ
ؔ࿈Ϋϥε • ManifestConfigSourceΫϥε • ઃఆͷಡΈࠐΈ • XmlConfigSourceΫϥε • network_security_config.xmlΛύʔε
ؔ࿈Ϋϥε • NetworkSecurityConfigΫϥε • XmlConfigSourceͰΠϯελϯεԽ͞ΕΔ • NetworkSecurityTrustManagerΫϥε • ূ໌ॻνΣοΫͱPinningνΣοΫΛ࣮ࢪ •
ূ໌ॻνΣοΫ࣮ॲཧdelegateͷ TrustManagerImplʹͤΔ
ؔ࿈Ϋϥε • TrustManagerImplΫϥε • ূ໌ॻνΣοΫͷ࣮ • https://github.com/google/conscrypt/blob/master/platform/ src/main/java/org/conscrypt/TrustManagerImpl.java • ߹ΘͤͯಡΉͱྑ͍
https://developer.android.com/training/ articles/security-ssl.html
Pinning Certificates <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest=“SHA-256”>{
hash value }</pin> <!-- backup pin --> <pin digest=“SHA-256”>{ hash value }</pin> </pin-set> </domain-config> </network-security-config> PinningͷظݶΛઃఆՄೳ ͷγεςϜ࣌ؒͱͷൺֱ ࠶ ׃
NetworkSecurityTrustManager private void checkPins(List<X509Certificate> chain) throws CertificateException { PinSet pinSet
= mNetworkSecurityConfig.getPins(); if (pinSet.pins.isEmpty() || System.currentTimeMillis() > pinSet.expirationTime || !isPinningEnforced(chain)) { return; } … } PinningͷظݶΛઃఆՄೳ ͷγεςϜ࣌ؒͱͷൺֱ
ҙ • ʮશͯཧղͨ͠ʯͱ͍ͬͯࣗͰ ࣮͠ͳ͍͜ͱ
Android NΑΓલͰ Pinning Certificates͢Δ
Pinning Certificates (ϐϯཹΊ) ɹ TrustKit-AndroidΛར༻ ɹ OkHttpClientͷcertificatePinnerΛར༻
Pinning Certificates (ϐϯཹΊ) → TrustKit-AndroidΛར༻ ɹ OkHttpClientͷcertificatePinnerΛར༻
TrustKit-AndroidΛར༻ • API 15+ • MIT License • NetworkSecurityConfigͷઃఆΛ ಡΈࠐΜͰূ໌ॻͷݕূΛ͢Δ
TrustKit-AndroidΛར༻ TrustKit.initializeWithNetworkSecurityConfiguration(this); URL url = new URL("https://www.datatheorem.com"); String serverHostname =
url.getHost(); // HttpsUrlConnection HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setSSLSocketFactory( TrustKit.getInstance().getSSLSocketFactory(serverHostname) ); // OkHttp 3.3.x and higher OkHttpClient client = new OkHttpClient().newBuilder() .sslSocketFactory( TrustKit.getInstance().getSSLSocketFactory(serverHostname), TrustKit.getInstance().getTrustManager(serverHostname) ) .build(); }
TrustKit-AndroidΛར༻ TrustKit.initializeWithNetworkSecurityConfiguration(this); URL url = new URL("https://www.datatheorem.com"); String serverHostname =
url.getHost(); // HttpsUrlConnection HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setSSLSocketFactory( TrustKit.getInstance().getSSLSocketFactory(serverHostname) ); // OkHttp 3.3.x and higher OkHttpClient client = new OkHttpClient().newBuilder() .sslSocketFactory( TrustKit.getInstance().getSSLSocketFactory(serverHostname), TrustKit.getInstance().getTrustManager(serverHostname) ) .build(); }
TrustKit-AndroidΛར༻ TrustKit.initializeWithNetworkSecurityConfiguration(this); URL url = new URL("https://www.datatheorem.com"); String serverHostname =
url.getHost(); // HttpsUrlConnection HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setSSLSocketFactory( TrustKit.getInstance().getSSLSocketFactory(serverHostname) ); // OkHttp 3.3.x and higher OkHttpClient client = new OkHttpClient().newBuilder() .sslSocketFactory( TrustKit.getInstance().getSSLSocketFactory(serverHostname), TrustKit.getInstance().getTrustManager(serverHostname) ) .build(); }
Pinning Certificates ɹ TrustKit-AndroidΛར༻ → OkHttpClientͷcertificatePinnerΛར༻
OkHttpClientͷcertificatePinnerΛར༻ public void run() throws Exception { OkHttpClient client =
new OkHttpClient.Builder() .certificatePinner(new CertificatePinner.Builder() .add("publicobject.com", “sha256/{ hash value }”) .build()) .build(); Request request = new Request.Builder() .url("https://publicobject.com/robots.txt") .build(); Response response = client.newCall(request).execute(); }
OkHttpClientͷcertificatePinnerΛར༻ public void run() throws Exception { OkHttpClient client =
new OkHttpClient.Builder() .certificatePinner(new CertificatePinner.Builder() .add("publicobject.com", “sha256/{ hash value }”) .build()) .build(); Request request = new Request.Builder() .url("https://publicobject.com/robots.txt") .build(); Response response = client.newCall(request).execute(); } PinningͷظݶΛઃఆෆՄ
Pinning Certificatesͷ ӡ༻
ӡ༻࣌ͷϙΠϯτ • αʔόʔαΠυͱͷௐ • SSLূ໌ॻΛม͑ΒΕΔͱ௨৴Ͱ͖ͳ͘ͳΔ • SSLূ໌ॻߋ৽࣌ͷϧʔϧ੍ఆ • Pinning CerficatesͷexpireઃఆͳͲ
ཧతͳӡ༻ Server ূ໌ॻAظݶ ূ໌ॻAϐϯཹΊ + expireઃఆͳ͠ Client
ཧతͳӡ༻ Server ূ໌ॻAظݶ Client ূ໌ॻBൃߦ ূ໌ॻAϐϯཹΊ + expireઃఆͳ͠
ཧతͳӡ༻ Server ূ໌ॻAظݶ Client ূ໌ॻBൃߦ ূ໌ॻA + BϐϯཹΊͷΞϓϦϦϦʔε ڧ੍Ξοϓσʔτ ূ໌ॻAϐϯཹΊ
+ expireઃఆͳ͠
ཧతͳӡ༻ Server ূ໌ॻAظݶ Client ূ໌ॻBൃߦ ূ໌ॻBʹΓସ͑ ূ໌ॻA + BϐϯཹΊͷΞϓϦϦϦʔε ڧ੍Ξοϓσʔτ
ূ໌ॻAϐϯཹΊ + expireઃఆͳ͠
ཧతͳӡ༻ͷؾ࣋ͪ • ৗʹPinning Certificates͕༗ޮ • ূ໌ॻͷೖΕସ͑ͷλΠϛϯάͰ༗ޮ • expireͷઃఆΛ͍Ε͍ͯͳ͍ͷͰ γεςϜ͕࣌ؒͣΕ͍ͯͯ༗ޮ
ཧతͳӡ༻ͷؾ࣋ͪ • ৗʹPinning Certificates͕༗ޮ • ূ໌ॻͷೖΕସ͑ͷλΠϛϯάͰ༗ޮ • expireͷઃఆΛ͍Ε͍ͯͳ͍ͷͰ γεςϜ͕࣌ؒͣΕ͍ͯͯ༗ޮ ⚠
ΞϓϦͷߋ৽ΛΕΔͱ௨৴Ͱ͖ͳ͘ͳΔ ⚠ ڧ੍Ξοϓσʔτ͕ඞཁ
expireઃఆʹΑΔଥڠҊ Server ূ໌ॻAظݶ Client ূ໌ॻAϐϯཹΊظݶ
expireઃఆʹΑΔଥڠҊ Server ূ໌ॻAظݶ Client ূ໌ॻAϐϯཹΊظݶ ূ໌ॻBൃߦ
expireઃఆʹΑΔଥڠҊ Server ূ໌ॻAظݶ Client ূ໌ॻAϐϯཹΊظݶ ূ໌ॻBൃߦ ূ໌ॻBʹΓସ͑
expireઃఆʹΑΔଥڠҊ Server ূ໌ॻAظݶ Client ূ໌ॻAϐϯཹΊظݶ ূ໌ॻBൃߦ ূ໌ॻBʹΓସ͑ ূ໌ॻBϐϯཹΊ൛ϦϦʔε
ଥڠҊͷؾ࣋ͪ • ΞϓϦͷߋ৽ΛΕͯ௨৴Ͱ͖Δ • ڧ੍Ξοϓσʔτ͕ඞཁͳ͍ • ূ໌ॻΓସ͑࣌ʹPinning͕ޮ͔ͳ͍ ࣌ظ͕͋Δ
·ͱΊ
·ͱΊ • HTTPΊ·͠ΐ͏ • NetworkSecurityConfigʹΑͬͯɺѱҙ ͷ͋Δ߈ܸऀ͔ΒϢʔβʔΛकΔઃఆ͕ ؆୯ʹͰ͖ΔΑ͏ʹͳΓ·ͨ͠ • ӡ༻࣌ؾΛ͚ͭ·͠ΐ͏
͝੩ௌ͋Γ͕ͱ͏ ͍͟͝·ͨ͠
Appendix • GMailͷϝοηʔδݟΒΕͨ https://www.computerworld.com/article/2510951/cybercrime-hacking/ hackers-spied-on-300-000-iranians-using-fake-google-certificate.html • ෆਖ਼ͳূ໌ॻ͕ൃߦ͞Εͨ http://www.atmarkit.co.jp/news/201109/08/diginotar.html