반응형
안드로이드 C2DM PUSH 문제 발생 시 에러 해결 방법 (GCM)
고전 자료입니다. 2015년 종료되었고, C2DM 서비스는 GCM 으로 대체되었습니다. 그냥 놔두긴 아까운 글이라 저장한다는 의미로 블로그에 글을 남깁니다.
C2DM = Cloud to Device Message (2015년 종료)
GCM = Google Cloud Messaging (C2DM 대체한 구글 서비스, 2019년 4월 종료)
안드로이드 앱에서 데이터 푸쉬할 때 SSLHandshakeException 발생하는 경우입니다.
예제 소스는 아래와 같으며, 뽐뿌 개발자 포럼에서 인용했습니다.
▷ Android C2DM PUSH 소스 코드 (파라미터 전달)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | StringBuffer postDataBuilder = new StringBuffer(); // device 인증 키 postDataBuilder.append("registration_id="+registration_id); postDataBuilder.append("&collapse_key=1"); postDataBuilder.append("&delay_while_idle=1"); // message postDataBuilder.append("&data.msg=" + URLEncoder.encode(msg, "UTF-8")); byte[] postData = postDataBuilder.toString().getBytes("UTF8"); URL url = new URL("https://android.clients.google.com/c2dm/send"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length",Integer.toString(postData.length)); // AUTH 키 conn.setRequestProperty("Authorization", "GoogleLogin auth="+auth); OutputStream out = conn.getOutputStream(); out.write(postData); out.close(); conn.getInputStream(); | cs |
구글 클라우드 서비스
▷ 위 안드로이드 예제 소스 실행 후 에러 메시지
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching android.clients.google.com found. at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241) ... ... Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching android.clients.google.com found. at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:193) at sun.security.util.HostnameChecker.match(HostnameChecker.java:77) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:264) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:250) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185) | cs |
핵심은 3줄은 이렇습니다.
- javax.net.ssl.SSLHandshakeException
- java.security.cert.CertificateException
- No subject alternative DNS name matching
▷ 해결 방법
Java SSL 일치하지 않거나, 신뢰할 수 없는 SSL 인증서 사용하면 예외가 발생할 수 있다고 합니다.
- Change certificate’s subject alternative value
- Create customize HostnameVerifier
안드로이드에서 IP 주소 사용하여 호스트로 접근할 땐 alternative 값을 IP로 변경해야 합니다. DNS 이름 사용할 때도 DNS 이름과 일치해야 합니다.
구글 클라우드 서비스
□ HostnameVerifier 클래스 생성
1 2 3 4 5 | private static class CustomizedHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } } | cs |
위 클래스를 SSL에 적용합니다.
1 2 | HttpsURLConnection connection = (HttpsURLConnection) new URL("https://url").openConnection(); connection.setHostnameVerifier(new CustomizedHostNameVerifier()); | cs |
이어서, 모든 SSL 커넥션에 적용합니다.
1 | HttpsURLConnection.setDefaultHostnameVerifier(new CustomizedHostnameVerifier()); | cs |
기본적으로 호스트 이름은 확인하지 않으므로 보안성 위험할 수 있는 방법입니다.
구글 클라우드 서비스
관련 글
- FPGA와 TCM를 이용한 임베디드 보안 시스템 개요 (TPM, 반도체, OS)
- 전자 화폐, 스마트 카드 보안 기술 TPM (Mobile TPM, mTpm)
- Trusted Platform Module, 스마트폰 보안 기술 TPM 설명
ⓒ written by vicddory
안드로이드 C2DM PUSH 문제 발생 시 에러 해결 방법 (GCM)
반응형