概述

App与服务器之间通过网络传输数据,需要确保数据在传输过程中的安全,保护传输数据的机密性和完整性,防止敏感数据被窃取和篡改是很重要的。推荐使用传输层安全协议(TLS)来保护网络传输数据的安全。

当App通过HTTPS访问云侧服务器时,如果App信任了用户安装的CA证书,则用户可以通过网络代理工具(如Fiddler、Charles)对HTTPS消息进行中间人攻击(如查看、篡改请求和响应消息),可能会导致App或云侧服务器产生安全风险,因此在通过HTTPS访问云侧服务器时应该配置CA证书进行合法性校验。

配置CA证书进行合法性校验

当App通过TLS协议连接服务器时,服务器会提供证书链来证明其身份,App需要使用可信的CA(证书颁发机构)证书对服务器证书链进行合法性校验。

服务器一般会根据场景使用不同类型CA颁发的证书链:

  1. 权威CA证书,如CFCA、GlobalSign CA机构的根CA证书,其CA证书满足业界的相关管理规范和通过审计认证,该类CA证书可信度高。
  2. 企业自建的CA证书,企业内部的服务器在不对外提供服务时,一般使用该类CA证书颁发的证书链,企业内部的App直接信任该CA证书。

系统提供了2种CA证书管理的能力,另外App也可自行管理CA证书:

  1. 系统预置CA证书:系统预置了业界主流的权威CA证书。
  2. 用户安装的CA证书:用户通过系统的设置界面安装的私有CA证书,这类CA证书可信度低。
  3. App管理的CA证书:App可以在Hap内预置可信的CA证书,例如企业内部自建的CA证书。

App应该根据业务的安全要求及应用场景进行网络连接安全配置,只信任可信的CA证书。

网络连接安全配置

配置信任系统预置的CA证书

面向互联网用户提供服务的App一般只需要信任系统预置CA证书。Network KitRemoteCommunication Kit的Https连接已默认信任系统预置的CA证书。

说明:

系统Network Kit和Remote Communication Kit的Https连接默认信任系统预置的CA证书和用户安装的CA证书,可通过配置SSL Pinning证书锁定提升安全。

如果App使用三方库进行网络连接,则需要手工设置系统预置的CA证书路径:/etc/security/certificates。

示例

使用三方库curl进行HTTPS连接,通过下面代码设置信任的CA证书路径:

curl_easy_setopt( curl, CURLOPT_CATH, "/etc/security/certificates");

配置信任App管理的CA证书

如果App服务器使用企业内部自建的CA证书,则App需要配置信任自建的CA证书,App可以把自建的CA证书内置到Hap包内。

Network Kit和Remote Communication Kit可以使用src/main/resources/base/profile/network\_config.json文件进行配置:把应用级信任的CA证书放到/res/appCaCert目录下,把特定域名信任的CA证书放到/res/domainCaCert目录下

{
  "network-security-config": {
    "base-config": {
      "trust-anchors": [
        {
          "certificates": "/res/appCaCert"
        }
      ]
    },
    "domain-config": [
      {
        "domains": [
          {
            "include-subdomains": true,
            "name": "example.com"
          }
        ],
        "trust-anchors": [
          {
            "certificates": "/res/domainCaCert"
          }
        ]
      }
    ]
  }
}

Network Kit也支持在发起HTTPS请求的代码中指定信任的CA证书路径

httpRequest.request( "EXAMPLE_URL",  {
    method: http.RequestMethod.POST, 
    header: {
      'Content-Type': 'application/json'
    },
    extraData: "data to send",
    expectDataType: http.HttpDataType.STRING, 
    connectTimeout: 60000, 
    caPath:'/res/domainCaCert', // 指定信任的CA证书路径
 }, (err: BusinessError, data: http.HttpResponse) => {
   … … 
}
Remote Communication Kit也支持在代码中[指定信任的CA证书路径](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/remote-communication-rcp-V5#section1597118916425):

```
const caPath: rcp.CertificateAuthority = {
   folderPath: '/res/appCaCert', // 指定信任的CA证书路径
}
const securityConfig: rcp.SecurityConfiguration = {
  remoteValidation: caPath
};
// Use the security configuration in the session creation
const sessionWithSecurityConfig = rcp.createSession({ requestConfiguration: { security: securityConfig } });
```

说明:

HarmonyOS Next 5.0版本Network Kit和Remote Communication Kit在进行上面的配置后,Https连接仍然信任系统预置的CA证书和用户安装的CA证书,可通过配置SSL Pinning证书锁定提升安全性。

App使用三方库进行网络连接,则需要在代码中设置App管理的CA证书路径。例如使用三方库curl进行HTTPS连接,通过下面代码设置信任的CA证书路径:

curl_easy_setopt( curl, CURLOPT_CATH, "/res/domainCaCert");

配置信任用户安装的CA证书

用户安装的CA证书可信度较低,除以下场景外,不建议App信任用户安装的CA证书:

1.App开发和调测过程中需要进行网络抓包定位问题和测试。用户通过系统的设置界面安装的CA证书,并保存在目录:/data/certificates/user\_cacerts/{userid} ,其中userid从100开始。

注意:在商用发布的App版本中不应该信任用户安装的CA证书。

2.面向2B企业应用的场景,App需要支持通过企业的代理服务器访问App服务器。设备通过企业的MDM系统或设备的管理员用户手工安装CA证书,并保存在目录:/data/certificates/user\_cacerts/0

配置SSL Pinning证书锁定

一般情况下App默认信任系统预置的CA证书,如果有预置的CA 颁发了不可信证书,则应用将面临攻击的风险,对网络安全比较高的App(如金融支付、银行类应用),可以通过配置SSL Pinning证书锁定的方式只信任指定服务器证书的公钥。

配置SSL Pinning:支持两种配置方式,二选一即可。

1.静态SSL pinning配置,通过network\_config.json文件进行配置:

{
  "network-security-config": {
    "domain-config": [
      {
        "domains": [
          {
            "include-subdomains": true,
            "name": "server.com"
          }
        ],
        "pin-set": {
          "expiration": "2024-11-08",
          "pin": [
            {
              "digest-algorithm": "sha256",
              "digest": "g8CsdcpyAKxmLoWFvMd2hC7ZDUy7L4E2NYOi1i8qEtE=" //服务器证书公钥的hash
            }
          ]
        }
      }
    ]
  }
}

具体可参考配置指导的“预置锁定证书PIN”章节。

2.动态SSL pinning:通过在代码中动态设置。

Network Kit配置动态SSL Pinning:

 certificatePinning: [ // 可选,支持证书锁定配置信息的动态设置,自API 12开始支持该属性
    {
      publicKeyHash: 'g8CsdcpyAKxmLoWFvMd2hC7ZDUy7L4E2NYOi1i8qEtE=', // 服务器证书公钥的hash
      hashAlgorithm: 'SHA-256' 
    }, {
      publicKeyHash: 'MGFiY2UyMDk5ZjEyMzI3MWQ4MDMyY2E4ODEzMmY3EtE=', // 服务器证书备用公钥的hash
      hashAlgorithm: 'SHA-256' 
    }
  ]

具体可参考配置指导的“certificatePinning”参数说明

Remote Communication Kit配置动态SSL Pinning:

  const keyHash: string = 'g8CsdcpyAKxmLoWFvMd2hC7ZDUy7L4E2NYOi1i8qEtE='; //服务器证书的公钥
  const session = rcp.createSession();
  const request = new rcp.Request(HTTP_SERVER);
  const pin: rcp.CertificatePinning = {
    kind: 'public-key',
    publicKeyHash: keyHash,
    hashAlgorithm: 'SHA-256'
  };
  request.configuration = {
    security: {
      certificatePinning: pin,
    }
  };
  const resp = await session.fetch(request);

具体可参考配置指导的“certificatePinning”参数说明

SSL Pinning的限制和约束:

Network kit的SSL pinning要求App云侧服务器证书的公钥不能变化,如有变化需要修改App内配置的证书公钥,否则App的网络连接会失败,因此建议SSL pinning配置始终包含至少一个备用公钥。

同时,App可以设置SSL pinning的到期时间,在该时间之后不再锁定证书。这有助于在服务器证书公钥变化时,防止还未更新的App出现连接性问题。但是设置SSL pinning的到期时间可能会使攻击者绕过证书锁定。

请App开发者对安全风险(如:App在应用层做了敏感信息的加密或签名,则安全风险较低)和SSL Pinning的限制约束进行充分的评估和决策是否配置。

总结

开发者应该结合App的业务场景,在不影响业务功能的情况下,合理设置可信CA证书的范围:

  1. 面向互联网用户的App,建议只需要信任系统预置的CA证书。
  2. 只访问企业内部服务器的App,建议只信任企业内部自建的CA证书。
  3. 同时访问企业内部服务器和互联网服务的App,建议根据访问的服务器域名分别配置信任系统预置的CA证书或企业内部自建的CA证书。
  4. App开发和调测过程中需要进行网络抓包定位问题和测试,建议只在调测版本信任用户安装的CA证书。
  5. App需要支持通过企业的代理服务器访问App服务器,可信任通过企业的MDM系统或设备的管理员用户手工安装CA证书,但设备的管理员用户可以通过代理工具对App网络数据进行抓包,建议App在应用层对敏感数据进行二次加密或签名。
  6. 对网络安全比较高的App(如金融支付、银行类应用),可通过SSL Pinning方式绑定服务器证书的公钥,进一步提升安全。

HarmonyOS码上奇行
6.7k 声望2.7k 粉丝