You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native是否支持双向传输层安全(mTLS)?求可行实现示例

React Native 双向传输层安全(mTLS)支持与实现示例

React Native 完全支持双向 TLS(mTLS),需要结合原生平台证书配置和网络请求库的自定义设置来完成实现,以下是具体步骤和代码示例:

一、前置准备

  • 客户端证书:通常为 .p12(PKCS#12)格式,包含客户端证书、私钥及对应密码
  • 服务器CA证书:用于验证服务器身份的根/中间证书,格式可为 .pem 或 .cer

二、原生平台配置

iOS 端

  1. 将证书文件(client.p12、ca.cer)添加到Xcode项目,勾选对应Target,并确认文件已在Build Phases > Copy Bundle Resources中
  2. 若服务器证书不符合ATS默认规则,在Info.plist添加ATS例外:
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <false/>
  <key>NSExceptionDomains</key>
  <dict>
    <key>your-server-domain.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.2</string>
    </dict>
  </dict>
</dict>

Android 端

  1. 将证书文件(client.p12、ca.pem)放入android/app/src/main/res/raw目录(无此目录则新建)
  2. 需通过自定义SSLSocketFactory加载证书,可参考后续原生代码片段

三、React Native 代码实现示例

1. 使用 Axios 实现 mTLS

先安装依赖:

npm install axios react-native-fs

请求代码示例:

import axios from 'axios';
import RNFS from 'react-native-fs';
import { Platform } from 'react-native';
import https from 'https';

// 加载证书文件
const loadCertificates = async () => {
  // 区分平台获取证书路径
  const clientP12Path = Platform.OS === 'ios' 
    ? `${RNFS.MainBundlePath}/client.p12` 
    : `${RNFS.DocumentDirectoryPath}/client.p12`;
  const caCertPath = Platform.OS === 'ios' 
    ? `${RNFS.MainBundlePath}/ca.cer` 
    : `${RNFS.DocumentDirectoryPath}/ca.pem`;

  // 读取证书内容为base64
  const clientP12 = await RNFS.readFile(clientP12Path, 'base64');
  const caCert = await RNFS.readFile(caCertPath, 'base64');

  return { clientP12, caCert, passphrase: 'your-p12-password' };
};

// 创建带mTLS的Axios实例
const createMtlsAxiosInstance = async () => {
  const { clientP12, caCert, passphrase } = await loadCertificates();

  const agent = new https.Agent({
    pfx: Buffer.from(clientP12, 'base64'),
    passphrase: passphrase,
    ca: Buffer.from(caCert, 'base64'),
    rejectUnauthorized: true // 开启服务器证书验证
  });

  return axios.create({
    httpsAgent: agent,
    baseURL: 'https://your-server-domain.com/api'
  });
};

// 请求使用示例
const fetchMtlsData = async () => {
  try {
    const axiosInstance = await createMtlsAxiosInstance();
    const response = await axiosInstance.get('/data');
    console.log('请求结果:', response.data);
  } catch (error) {
    console.error('mTLS请求失败:', error);
  }
};

2. 使用 Fetch API 实现 mTLS(需原生桥接)

Fetch API本身不支持直接配置证书,需通过原生模块桥接实现:

Android 原生代码片段(自定义OkHttpClient)

import android.content.Context;
import okhttp3.OkHttpClient;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

public class MtlsClientHelper {
    public static OkHttpClient createMtlsClient(Context context) {
        try {
            // 加载CA证书
            InputStream caInput = context.getResources().openRawResource(R.raw.ca);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);
            trustStore.setCertificateEntry("ca", cf.generateCertificate(caInput));
            caInput.close();

            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(trustStore);

            // 加载客户端证书
            InputStream keyInput = context.getResources().openRawResource(R.raw.client);
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(keyInput, "your-p12-password".toCharArray());
            keyInput.close();

            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyStore, "your-p12-password".toCharArray());

            // 初始化SSL上下文
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

            return new OkHttpClient.Builder()
                    .sslSocketFactory(sslContext.getSocketFactory(), (javax.net.ssl.X509TrustManager) tmf.getTrustManagers()[0])
                    .build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

之后通过React Native原生模块桥接,将自定义OkHttpClient注入网络请求流程,或直接封装原生请求方法供RN调用。

四、注意事项

  • 敏感信息安全:客户端证书密码不要硬编码,建议使用react-native-keychain存储
  • 平台差异:iOS与Android证书加载路径、处理逻辑略有不同,需分别适配
  • 证书有效期:定期检查并更新过期的客户端/CA证书

内容的提问来源于stack exchange,提问作者Sushil Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:44:57