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

发布于 2024-11-05 02:03:40 字数 2211 浏览 0 评论 0原文

当尝试通过 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);
    }

}

似乎其他人也遇到了这个问题,但我一直无法找到明确的解决方案(至少我无法理解)。感谢任何帮助。

I'm receiving the following SSLHandshakeException when trying to send a push notification through the C2DM servers.

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

The code to send the message is as follows, and is running on App Engine. Everything works fine when I use cURL, so I know that the server authentication code and device registration ID are correct.

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);
    }

}

It seems like others have also had this problem, but I haven't been able to find a clear solution (at least not one I'm able to understand). Appreciate any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

百善笑为先 2024-11-12 02:03:40

您需要使用 HttpsURLConnection 而不是 HttpURLConnection

AFAIK,HttpURLConnection 不验证主机名。

You need to use HttpsURLConnection instead of HttpURLConnection.

AFAIK, HttpURLConnection doesn't verify hostnames.

淤浪 2024-11-12 02:03:40

如果您处于测试阶段,您可以使用非安全 URL 来推送通知。

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

我还通过添加证书验证回调来接受任何证书来解决此问题,但这是在 C# 服务器上。我确信 Java 中有一个与此相当的东西。

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

If you are in the testing phase, you could use the non-secure url to push a notification.

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

I also got around this issue by adding a certificate validation callback to accept any certificate, but this was on a C# server. I'm sure there is a Java equivalent for this.

In production code you would want to verify the correct certificate or maybe just encrypt the data you are sending.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文