Last active
November 29, 2019 07:30
-
-
Save pich4ya/c7eaaa90e6de37a4a4c067026fa83ffe to your computer and use it in GitHub Desktop.
วิธีการไม่ trust all HTTPS cert เวลาต่อ internal API ที่ API server ใช้ cert ที่ issue มาจาก internal root CA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
ต้อง | |
- แน่ใจว่ามีไฟล์ root certificate แล้ว | |
- ตั้ง $JAVA_HOME ให้ถูกที่ และแน่ใจว่ามีโฟล์ $JAVA_HOME/jre/lib/security/cacerts | |
- รหัสผ่านของ Java keystore เป็นคำว่า changeit โดยค่า default | |
วิธีการ | |
1. ต้องไปดาวน์โหลดหรือขอ root certificate ที่จะใช้มาก่อน | |
Root certificates contain public information and CAs always make them available for anyone. | |
$ wget https://sth.sh/demo/STH_Root_CA.pem -O ca.pem | |
2. แปลง root certificate เป็น DER format | |
If you were able to obtain the root certificate in DER format, skip this step. | |
For the root certificate in PEM format: | |
$ openssl x509 -in ca.pem -inform pem -out ca.der -outform der | |
3. ยืนยันว่า root certificate ที่แปลงมาถูกต้อง | |
Ensure that the Java keytool can parse the certificate and display its content: | |
$ keytool -v -printcert -file ca.der | |
... output ... | |
Owner: CN=*.p7z.pw, O=Siam Thanat Hack, L=Bangkok, ST=Bangkok, C=TH | |
Issuer: CN=*.p7z.pw, O=Siam Thanat Hack, L=Bangkok, ST=Bangkok, C=TH | |
Serial number: 58af62466935090fa4a43b0206799cd956e28a07 | |
Valid from: Mon Oct 21 20:04:21 ICT 2019 until: Thu Oct 18 20:04:21 ICT 2029 | |
Certificate fingerprints: | |
SHA1: 5E:F4:48:63:83:E2:D8:4E:6D:C1:B2:0C:07:07:7E:19:04:41:2B:95 | |
SHA256: CB:06:7E:A5:7B:F3:F6:C3:FF:9E:9F:3A:81:F3:94:AA:D5:3B:BE:31:06:87:24:82:37:AD:D4:AC:F5:E8:BA:A7 | |
... | |
4. Import ไฟล์ root certificate เข้าไปใน Java system root CA store | |
$ sudo keytool -importcert -alias STHinternalCA -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -file ca.der | |
... output ... | |
Trust this certificate? [no]: yes | |
Certificate was added to keystore | |
5. ยืนยันว่า root certificate ถูก import สำเร็จแล้ว | |
$ keytool -keystore "$JAVA_HOME/jre/lib/security/cacerts" -storepass changeit -list | grep -i STHinternalCA | |
... output ... | |
sthinternalca, Nov 29, 2019, trustedCertEntry, | |
ต่อมาตอนรัน web หรือ app ที่เขียนด้วย Java ต้องใส่ออฟชั่น -D และใส่ค่าดังนี้ (ขึ้นกับวิธีการ deployment) | |
javax.net.ssl.trustStore=/path/to/jre/lib/security/cacerts | |
javax.net.ssl.trustStorePassword=changeit | |
ต่อมา Java จะต่อ HTTPS โดยยืนยันผ่าน root cert ใน Java keystore ให้เองเลยไม่ต้องทำอะไร | |
ตัวอย่างนี้ใช้ javax.net.ssl.HttpsURLConnection | |
*/ | |
String params = "client_id=" + clientID + "&client_secret=" + clientSecret + "&grant_type=client_credentials"; | |
URL obj = new URL(url); | |
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); | |
BufferedReader in; | |
// add reuqest header | |
con.setRequestMethod("POST"); | |
con.setRequestProperty("User-Agent", "Mozilla/5.0"); | |
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); | |
// Send post request | |
con.setDoOutput(true); | |
DataOutputStream wr = new DataOutputStream(con.getOutputStream()); | |
wr.writeBytes(params); | |
wr.flush(); | |
wr.close(); | |
int responseCode = con.getResponseCode(); | |
if (responseCode >= 400) | |
in = new BufferedReader(new InputStreamReader(con.getErrorStream())); | |
else | |
in = new BufferedReader(new InputStreamReader(con.getInputStream())); | |
String inputLine; | |
StringBuffer response = new StringBuffer(); | |
while ((inputLine = in.readLine()) != null) { | |
response.append(inputLine); | |
} | |
in.close(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-- วิธีที่ 2
ถ้าไม่ต้องการใส่ custom root cert ใน Java system CAs ก็ใส่แยกเป็นไฟล์
$ keytool -genkey -alias internalAPI -keyalg RSA -keystore truststore.jks -keysize 2048
... output ...
Enter keystore password: // รหัสผ่านนี้ใช้แค่เพื่อเข้า public information + public key
Re-enter new password:
What is your first and last name?
...
$ keytool -import -v -trustcacerts -alias server-alias -file server.cer -keystore truststore.jks -keypass changeit -storepass changeit
แล้วทำตาม https://stackoverflow.com/a/24561444 โดยให้ ยืนยัน HTTPS ด้วย cert ใน keystore ที่เราสร้างมา
-- วิธีที่ 3
ทำ certificate pinning
https://github.com/Flowdalic/java-pinning