Android C2DM:无法验证SSL证书javax.net.ssl.SSLHandshakeException

时间:2011-05-05 08:37:47

标签: java android android-c2dm sslhandshakeexception

尝试通过C2DM服务器发送推送通知时,我收到以下SSLHandshakeException。

javax.net.ssl.SSLHandshakeException: Could not verify SSL certificate for: https://android.apis.google.com/c2dm/send

发送消息的代码如下所示,并且正在App Engine上运行。当我使用cURL时,一切正常,所以我知道服务器身份验证代码和设备注册ID是正确的。

public static void sendHttpPostToC2dmService(String msg, PrintWriter out) {

    String authCode = "XXXX";
    String regID = "YYYY";

    try {
        URL url = new URL("https://android.apis.google.com/c2dm/send");

        String data = URLEncoder.encode("registration_id", "UTF-8") + "="
                + URLEncoder.encode(regID, "UTF-8");
        data += "&"
                + URLEncoder.encode("Authorization: GoogleLogin auth",
                        "UTF-8") + "="
                + URLEncoder.encode(authCode, "UTF-8");
        data += "&" + URLEncoder.encode("collapse_key", "UTF-8") + "="
                + URLEncoder.encode("something", "UTF-8");
        data += "&" + URLEncoder.encode("data.message", "UTF-8") + "="
                + URLEncoder.encode(msg, "UTF-8");

        out.println("data=" + data);

        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");

        OutputStreamWriter writer = new OutputStreamWriter(
                connection.getOutputStream());
        writer.write(data);
        writer.close();

        out.println("responseCode=" + connection.getResponseCode());

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            String responseLine = new BufferedReader(new InputStreamReader(
                    connection.getInputStream())).readLine();
            out.println("responseLine=" + responseLine);

        } else {
            // Server returned HTTP error code.
        }
    } catch (MalformedURLException e) {
        out.println("MalformedURL");
        out.println(e.getMessage());
    } catch (IOException e) {
        out.println("IOException");
        out.println(e.getMessage());
        e.printStackTrace(out);
    }

}

似乎其他人也有这个问题,但我找不到一个明确的解决方案(至少没有一个我能理解)。感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

您需要使用HttpsURLConnection代替HttpURLConnection

AFAIK,HttpURLConnection无法验证主机名。

答案 1 :(得分:0)

如果您处于测试阶段,则可以使用非安全网址来发送通知。

http://android.apis.google.com/c2dm/send

我也通过添加证书验证回调来接受任何证书来解决这个问题,但这是在C#服务器上。我确信这有一个Java等价物。

在生产代码中,您需要验证正确的证书,或者只是加密您要发送的数据。