【问题标题】:Ignore SSL Certificate Check on Android React Native忽略 Android React Native 上的 SSL 证书检查
【发布时间】:2023-03-30 06:34:01
【问题描述】:

我目前正在 Android 上使用 react native 工作。我正在使用 fetch() 发出 api 请求,但请求给我一个网络请求失败,这是由于端点没有 ssl 证书。通过修改一些 xcode 文件,我能够在 iOS 上删除此检查。 有没有办法在 Android 上忽略 ssl 证书检查?

【问题讨论】:

  • 有什么解决办法吗?

标签: javascript android ssl networking react-native


【解决方案1】:
/**
 * Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
 * aid testing on a local box, not for use on production.
 */
private static void disableSSLCertificateChecking() {
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }
    } };

    try {
        SSLContext sc = SSLContext.getInstance("TLS");

        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

在这里找到这个:https://gist.github.com/aembleton/889392。不太确定它是否有效,但它是一个开始!

【讨论】:

  • 嗨,女巫文件,我应该粘贴它吗?
【解决方案2】:

我也面临同样的问题。我使用了库 rn-fetch-blob。并将以下代码粘贴到 index.js 中。

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import RNFetchBlob from 'rn-fetch-blob';

AppRegistry.registerComponent(appName, () => App);
const Fetch = RNFetchBlob.polyfill.Fetch
// replace built-in fetch
window.fetch = new Fetch({
     // enable this option so that the response data conversion handled automatically
     auto : true,
    // when receiving response data, the module will match its Content-Type header
   // with strings in this array. If it contains any one of string in this array, 
  // the response body will be considered as binary data and the data will be stored
  // in file system instead of in memory.
  // By default, it only store response data to file system when Content-Type 
  // contains string `application/octet`.
  binaryContentTypes : [
    'image/',
    'video/',
    'audio/',
    'foo/',
 ],
 trusty : true
}).build()

如果仍然存在,您在 Android 中遇到 SSL 握手问题,请尝试使用以下解决方案。并从 MainApplication.java 中的 onCreate() 调用以下函数:-

 import android.annotation.SuppressLint;
 import java.security.SecureRandom;
 import java.security.cert.X509Certificate;

 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;

 public class MainApplication extends Application implements ReactApplication {
    @Override
    public void onCreate() {
         super.onCreate();
         handleSSLHandshake();
         SoLoader.init(this, /* native exopackage */ false);
         initializeFlipper(this); // Remove this line if you don't want Flipper enabled
    }

    /**
    * Enables https connections
    */
   @SuppressLint("TrulyRandom")
    public static void handleSSLHandshake() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
               public X509Certificate[] getAcceptedIssuers() {
                  return new X509Certificate[0];
               }

              @Override
              public void checkClientTrusted(X509Certificate[] certs, String authType) {
              }

               @Override
               public void checkServerTrusted(X509Certificate[] certs, String authType) {
               }
           }};

           SSLContext sc = SSLContext.getInstance("SSL");
           sc.init(null, trustAllCerts, new SecureRandom());


     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
          HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
               @Override
               public boolean verify(String arg0, SSLSession arg1) {
                  return true;
              }
           });
      } catch (Exception ignored) {
      }
    } 
 }

【讨论】:

  • letsencrypt 于 2014 年开始颁发免费证书。你们没有为开发设置制作有效的 SSL 证书,而是削弱了应用程序的安全性并制作了错误的代码 sn-ps 被使用(复制/粘贴)成千上万的初级开发人员。你确定你正确地解决了这个问题吗?您不应该为您的开发服务器制作有效的 ssl 证书而不是破坏应用程序吗?
  • 是的@MaximSagaydachny 需要为开发制作一个有效的 SSL 证书,但我正在前端工作,以便解决我在上述解决方案中使用的这个问题。我不知道后端人员不使用有效 SSL 证书的原因。
  • 这个解决方案对我有用。使用 React-native 版本 0.62
【解决方案3】:

注意:这是肮脏的解决方案

你可以修补 webview 包

转到node_modules/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java

onReceivedSslError 中将 handler.cancel() 更改为 handler.proceed();像这样

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
   // before: handler.cancel();
  handler.proceed();
}

如果你想做补丁包,那么你可以使用这个patch-package

【讨论】:

    猜你喜欢
    • 2021-09-26
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    相关资源
    最近更新 更多