【问题标题】:Connecting to the Parse Server on a VPS using https (self-sined cert for SSL)使用 https(SSL 的自签名证书)连接到 VPS 上的 Parse 服务器
【发布时间】:2016-06-18 15:28:18
【问题描述】:

由于某些原因,Parse 用户必须将他们的 Parse 环境迁移到 VPS(我的问题就是这种情况)或 Heroku、AWS(不需要这些平台)等。有一个新的 Parse SDK for Android (1.13 .0) 允许使用新的 Parse 接口初始化连接,如下所示:

Parse.initialize(new Parse.Configuration.Builder(this)
                .applicationId("myAppId")
                .clientKey(null) 
                .addNetworkInterceptor(new ParseLogInterceptor())
                .server("https://VPS_STATIC_IP_ADDRESS/parse/").build());

这种请求是使用端口 443 完成的。适当的 .js (nodejs) 连接器文件已被编辑,以便端口 443 本地连接到端口 1337(端口侦听器),并且在访问 Parse Server 时工作在浏览器中(当然是远程的:从 VPS 外部),可以应用自签名证书并走得更远。但是当一个 Android 应用程序(启动器)尝试连接它时,由于自签名证书而无法连接。 Parse SDK 中是否有可能应用自签名证书?

附:是否确实存在与此问题有关的错误,这就是发布 1.13.1 Parse 版本的原因?如果是的话,在哪里可以获得这个版本的jar-library?

谢谢!

【问题讨论】:

  • 你应该改正标题中的错字...

标签: java android parse-platform https self-signed


【解决方案1】:

我刚刚解决了这个问题- Parse SDK for android 在 SelfSigned 证书中不提供开箱即用的支持。 您需要自己修改代码。

第一步 - 相关代码在 ParseHttpClient 中

  public static ParseHttpClient createClient(int socketOperationTimeout,
      SSLSessionCache sslSessionCache) {
    String httpClientLibraryName;
    ParseHttpClient httpClient;
    if (hasOkHttpOnClasspath()) {
      httpClientLibraryName = OKHTTP_NAME;
      httpClient =  new ParseOkHttpClient(socketOperationTimeout, sslSessionCache);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      httpClientLibraryName = URLCONNECTION_NAME;
      httpClient =  new ParseURLConnectionHttpClient(socketOperationTimeout, sslSessionCache);
    } else {
      httpClientLibraryName = APACHE_HTTPCLIENT_NAME;
      httpClient =  new ParseApacheHttpClient(socketOperationTimeout, sslSessionCache);
    }
    PLog.i(TAG, "Using " + httpClientLibraryName + " library for networking communication.");
    return httpClient;   }

如果您的目标支持是更高级的版本,那么 KITKAT - 然后你需要在 ParseURLConnectionHttpClient 构造函数中添加:

    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){

            public boolean verify(String hostname, SSLSession session) {
                if(hostname.equals("YOUR TARGET SERVER")) {
                    return true;
                }
                return false;
            }});

在其他情况下(旧版本),代码将落入 Apache,我无法使用它 - 所以我做了以下事情:我将 okhttp 库添加到我的应用程序中(使用版本 2.4 - 相同的解析在 build 中表示,最近的包名称不同),然后代码将进入第一个条件,因为它会在路径上找到 okhttp。 您可能应该替换 if 条件顺序,这样它只会在低于 KITKAT 的版本上发生。

在 ParseOkHttpClient 中添加以下自签名证书代码:

   public void initCert() {
    try {
        Log.i("PARSE","initCert");

        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        String yairCert = "-----BEGIN CERTIFICATE-----\n" +
                YOUR CERTIFICATE HERE
                "-----END CERTIFICATE-----\n";
        InputStream caInput = new ByteArrayInputStream(yairCert.getBytes());
        Certificate ca = null;
        try {
            ca = cf.generateCertificate(caInput);
            System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
        } catch (CertificateException e) {
            e.printStackTrace();
        } finally {
            try {
                caInput.close();
            } catch (IOException e) {
                Log.e("PARSE_BUG","Failure on Cert installing",e);
                e.printStackTrace();
            }
        }

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);
        Log.i("PARSE","Initiating Self Signed cert");
        okHttpClient.setSslSocketFactory(context.getSocketFactory());
        try {
            cf = CertificateFactory.getInstance("X.509");
        } catch (CertificateException e) {
            Log.e("PARSE_BUG","Failure on Cert installing",e);
            e.printStackTrace();
        }
    } catch (IOException e) {
        Log.e("PARSE_BUG","Failure on Cert installing",e);
        e.printStackTrace();
    } catch (CertificateException e) {
        Log.e("PARSE_BUG","Failure on Cert installing",e);
        e.printStackTrace();

    } catch (NoSuchAlgorithmException e) {
        Log.e("PARSE_BUG","Failure on Cert installing",e);
        e.printStackTrace();
    } catch (KeyStoreException e) {
        Log.e("PARSE_BUG","Failure on Cert installing",e);
        e.printStackTrace();
    } catch (KeyManagementException e) {
        Log.e("PARSE_BUG","Failure on Cert installing",e);
        e.printStackTrace();
    }

最后一部分是调用这个方法+验证主机名,它也应该发生在构造函数中。 初始化证书(); okHttpClient.setHostnameVerifier(新的 HostnameVerifier() { @覆盖 公共布尔验证(字符串 s,SSLSession sslSession){ if(s.equals("你的目标服务器")) { 返回真; } 返回假; } });

就是这样。在本地构建 PARSE 并部署到您的应用程序,它会像魅力一样工作。

享受

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-10
    • 2012-12-31
    • 1970-01-01
    • 2023-03-15
    • 2016-03-01
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    相关资源
    最近更新 更多