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

React Native中如何实现https.Agent的证书认证功能?

React Native 实现客户端证书认证(替代Node.js https.Agent)

问题背景

需要将以下cURL请求转换为React Native的API请求:

curl -L -i -X PUT –cert ./[device_cert].pem –key ./[device_cert_private_key].pem -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' -d '{"registrationId": "[registration_id]"}' https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01

最初尝试用Axios结合Node.js的https.Agent实现,但React Native不支持https模块;试过rn-nodeify、node-libs-react-native等包,导致应用体积大幅增加,也无法使用nodejs-mobile-react-native。需要找到轻量的替代方案。

可行解决方案

方案1:封装原生网络模块(轻量可控)

React Native的JS层不支持客户端证书配置,但可以通过原生层(iOS/Android)实现带证书的网络请求,再封装成RN模块供JS调用。

iOS端核心实现(Objective-C)

使用NSURLSession配置客户端凭证:

// 读取本地证书和私钥文件
NSData *certData = [NSData dataWithContentsOfFile:certPath];
NSData *keyData = [NSData dataWithContentsOfFile:keyPath];

// 创建证书引用与身份凭证
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
SecIdentityRef identity = NULL;
OSStatus status = SecIdentityCreateWithCertificate(NULL, cert, &identity);

NSArray *certificates = @[(__bridge id)cert];
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:certificates persistence:NSURLCredentialPersistencePermanent];

// 配置URLSession
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

// 代理方法中提供客户端证书
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
    } else {
        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
    }
}

Android端核心实现(Kotlin)

使用OkHttpClient配置SSL上下文:

// 读取证书与私钥文件
val certFile = File(certPath)
val keyFile = File(keyPath)

// 转换为KeyStore(推荐提前将pem+key合并为p12格式简化处理)
val keyStore = KeyStore.getInstance("PKCS12")
keyStore.load(null, null)
// 注:若使用分离的pem/key,需借助BouncyCastle库解析后存入KeyStore

// 初始化SSLContext
val sslContext = SSLContext.getInstance("TLS")
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
keyManagerFactory.init(keyStore, "cert-password".toCharArray())
sslContext.init(keyManagerFactory.keyManagers, null, null)

// 构建带证书的OkHttpClient
val client = OkHttpClient.Builder()
    .sslSocketFactory(sslContext.socketFactory, getDefaultTrustManager())
    .build()

// 执行PUT请求
val request = Request.Builder()
    .url(apiUrl)
    .put(RequestBody.create(MediaType.parse("application/json"), jsonData))
    .build()
val response = client.newCall(request).execute()

最后通过React Native的NativeModules将原生请求封装为JS可调用的异步方法。

方案2:优化react-native-ssl-pinning配置

如果之前使用react-native-ssl-pinning的方式有误,可调整配置直接支持客户端证书,无需引入庞大的Node.js依赖:

import RNSslPinning from 'react-native-ssl-pinning';

const data = { registrationId: registrationId };

try {
  const response = await RNSslPinning.put(
    `https://global.azure-devices-provisioning.net/${scopeId}/registrations/${registrationId}/register?api-version=2021-06-01`,
    {
      headers: {
        'Content-Type': 'application/json',
        'Content-Encoding': 'utf-8'
      },
      body: JSON.stringify(data),
      sslPinning: {
        cert: certificatePath, // 本地pem证书路径
        key: keyPath, // 本地私钥路径
        passphrase: '' // 私钥密码(无则留空)
      }
    }
  );
  return response.data;
} catch (err) {
  console.error(err);
  return err;
}

方案3:合并PEM证书与私钥为PKCS12格式

将分离的.pem证书和私钥合并为.p12文件,可大幅简化RN端的证书处理流程:

# 使用OpenSSL合并命令
openssl pkcs12 -export -in device_cert.pem -inkey device_cert_private_key.pem -out device_cert.p12 -name "device-cert"

合并后可直接在原生模块或react-native-ssl-pinning中配置p12文件路径与密码,无需单独处理证书和私钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:00:03