안드로이드 C2DM PUSH 문제 발생 시 에러 해결 방법 (GCM)

안드로이드 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



안드로이드 C2DM PUSH 문제 발생 시 에러 해결 방법 (GCM)구글 클라우드 서비스


▷ 위 안드로이드 예제 소스 실행 후 에러 메시지


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줄은 이렇습니다.


  1. javax.net.ssl.SSLHandshakeException
  2. java.security.cert.CertificateException
  3. No subject alternative DNS name matching

▷ 해결 방법



Java SSL 일치하지 않거나, 신뢰할 수 없는 SSL 인증서 사용하면 예외가 발생할 수 있다고 합니다.


  • Change certificate’s subject alternative value
  • Create customize HostnameVerifier


안드로이드에서 IP 주소 사용하여 호스트로 접근할 땐 alternative 값을 IP로 변경해야 합니다. DNS 이름 사용할 때도 DNS 이름과 일치해야 합니다.


안드로이드 gcm 중단구글 클라우드 서비스


□ 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


기본적으로 호스트 이름은 확인하지 않으므로 보안성 위험할 수 있는 방법입니다.


안드로이드 c2dm gcm구글 클라우드 서비스



관련 글



ⓒ written by vicddory

안드로이드 C2DM PUSH 문제 발생 시 에러 해결 방법 (GCM)

댓글(0)

Designed by JB FACTORY