网络连接安全配置开发实践
概述 App与服务器之间通过网络传输数据,需要确保数据在传输过程中的安全,保护传输数据的机密性和完整性,防止敏感数据被窃取和篡改是很重要的。推荐使用传输层安全协议(TLS)来保护网络传输数据的安全。 当App通过HTTPS访问云侧服务器时,如果App信任了用户安装的CA证书,则用户可以通过网络代理工具
概述
App与服务器之间通过网络传输数据,需要确保数据在传输过程中的安全,保护传输数据的机密性和完整性,防止敏感数据被窃取和篡改是很重要的。推荐使用传输层安全协议(TLS)来保护网络传输数据的安全。
当App通过HTTPS访问云侧服务器时,如果App信任了用户安装的CA证书,则用户可以通过网络代理工具(如Fiddler、Charles)对HTTPS消息进行中间人攻击(如查看、篡改请求和响应消息),可能会导致App或云侧服务器产生安全风险,因此在通过HTTPS访问云侧服务器时应该配置CA证书进行合法性校验。
配置CA证书进行合法性校验
当App通过TLS协议连接服务器时,服务器会提供证书链来证明其身份,App需要使用可信的CA(证书颁发机构)证书对服务器证书链进行合法性校验。
服务器一般会根据场景使用不同类型CA颁发的证书链:
- 权威CA证书,如CFCA、GlobalSign CA机构的根CA证书,其CA证书满足业界的相关管理规范和通过审计认证,该类CA证书可信度高。
- 企业自建的CA证书,企业内部的服务器在不对外提供服务时,一般使用该类CA证书颁发的证书链,企业内部的App直接信任该CA证书。
系统提供了2种CA证书管理的能力,另外App也可自行管理CA证书:
- 系统预置CA证书:系统预置了业界主流的权威CA证书。
- 用户安装的CA证书:用户通过系统的设置界面安装的私有CA证书,这类CA证书可信度低。
- App管理的CA证书:App可以在Hap内预置可信的CA证书,例如企业内部自建的CA证书。
App应该根据业务的安全要求及应用场景进行网络连接安全配置,只信任可信的CA证书。
网络连接安全配置
配置信任系统预置的CA证书
面向互联网用户提供服务的App一般只需要信任系统预置CA证书。Network Kit和RemoteCommunication 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证书路径:
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证书的范围:
- 面向互联网用户的App,建议只需要信任系统预置的CA证书。
- 只访问企业内部服务器的App,建议只信任企业内部自建的CA证书。
- 同时访问企业内部服务器和互联网服务的App,建议根据访问的服务器域名分别配置信任系统预置的CA证书或企业内部自建的CA证书。
- App开发和调测过程中需要进行网络抓包定位问题和测试,建议只在调测版本信任用户安装的CA证书。
- App需要支持通过企业的代理服务器访问App服务器,可信任通过企业的MDM系统或设备的管理员用户手工安装CA证书,但设备的管理员用户可以通过代理工具对App网络数据进行抓包,建议App在应用层对敏感数据进行二次加密或签名。
- 对网络安全比较高的App(如金融支付、银行类应用),可通过SSL Pinning方式绑定服务器证书的公钥,进一步提升安全。
更多推荐
所有评论(0)