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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
レガシーな広告配信システムでのAI駆動開発/運用の挑戦
i16fujimoto
0
120
AIはどのように 組織のアジリティを変えるのか?
junki
4
1.4k
【FinOps】データドリブンな意思決定を目指して
z63d
0
340
Zenoh on Zephyr on LiteX
takasehideki
2
110
When Platform Engineering Meets GenAI
sucitw
0
170
Comment regagner la souveraineté de vos données tout en étant payé grâce à Nostr !
rlifchitz
0
200
MUSUBI 田中裕一『AIと共に行う「しごとのリデザイン」- スモールバックオフィス編』AI Ops Lab #4
musubi
0
310
WebGIS AI Agentの紹介
_shimizu
0
560
Flow 不死:AI 時代 DevOps 的不變本質
cheng_wei_chen
2
510
脱SaaS!FDEを支えるプロビジョニングと分離設計
knih
0
300
飲食店もAIで。レジ締めやハンディシステムをつくってる話 / Using AI for restaurant management
vtryo
0
170
AIAU_UMEMOGU_ninomiya_slide
ninomiya_ii
0
260
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
4 Signs Your Business is Dying
shpigford
187
22k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Rails Girls Zürich Keynote
gr2m
96
14k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Test your architecture with Archunit
thirion
1
2.3k
Navigating Weather and Climate Data
rabernat
0
230
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
240
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
610
HDC tutorial
michielstock
2
720
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
540
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