HarmonyOS App Network Security: Configure CA Trust & SSL Pinning
This guide details how to secure HarmonyOS app network connections by configuring trusted CA certificates for server validation, disabling user-installed CAs to prevent MITM attacks, and implementing SSL pinning for high-security applications like banking.
Overview
Data transmission between HarmonyOS applications and servers must ensure confidentiality and integrity to prevent sensitive data theft and tampering. The Transport Layer Security (TLS) protocol is recommended for protecting data security.
When an app accesses a cloud server via HTTPS, trusting user-installed CA certificates allows network proxy tools such as Fiddler or Charles to perform man-in-the-middle (MITM) attacks — viewing and modifying request and response messages — creating security risks for both the app and the server. Therefore, CA certificate validation must be configured for HTTPS connections.
Configuring CA Certificates for Server Validation
During a TLS connection, the server presents a certificate chain to prove its identity. The app must validate this chain using trusted CA (Certificate Authority) certificates.
Server Certificate Types
Authoritative CA certificates — e.g., CFCA, GlobalSign root CA certificates, which meet industry management standards and pass audits, offering high trust.
Enterprise self-built CA certificates — used for internal enterprise server certificate chains. Internal enterprise apps directly trust these CA certificates.
Three CA Certificate Management Methods
System pre-installed CA certificates — the system includes mainstream authoritative CA certificates.
App-managed CA certificates — the app can pre-install trusted CA certificates in the HAP package, such as enterprise self-built CA certificates.
User-installed CA certificates — private CA certificates installed via system settings. These have lower trustworthiness and may be used for MITM attacks.
Scenario-Based Trust Configuration Recommendations
Internet-facing apps — trust only system pre-installed CA certificates.
Enterprise-internal-only apps — trust only app-managed CA certificates.
Hybrid apps (internal + internet) — configure trust per server domain: system pre-installed CAs for internet domains, app-managed CAs for internal domains.
Development and debugging — trust user-installed CA certificates only in debug builds for packet capture (e.g., Fiddler, Charles). Note: Production releases must not trust user-installed CAs.
Enterprise proxy access (2B apps) — trust CA certificates installed by enterprise MDM or device administrators (stored in /data/certificates/user_cacerts/0). However, admins may proxy and capture app traffic; implement application-layer protections such as secondary encryption or signing of sensitive data.
High-security apps (finance, banking) — after CA configuration, add SSL Pinning to bind the server certificate's public key for enhanced security.
Network Connection Security Configuration
Trust System Pre-installed CA Certificates
If the app uses third-party libraries for network connections, manually set the system pre-installed CA certificate path: /etc/security/certificates.
Example (curl):
curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/security/certificates");Distrust User-Installed CA Certificates
For Network Kit and Remote Communication Kit, configure in src/main/resources/base/profile/network_config.json:
{
"network-security-config": {
...
},
"trust-global-user-ca": false, // Trust CA installed by enterprise MDM or device admin (default true)
"trust-current-user-ca": false // Trust CA installed by current user (default true)
}Trust App-Managed CA Certificates
If the app server uses an enterprise self-built CA, pre-install those CA certificates in the HAP and configure trust.
Network Kit and Remote Communication Kit use network_config.json. Example: place app-level trusted CA certs in /data/storage/el1/bundle/entry/resources/resfile/appCaCert, domain-specific trusted CA certs in
/data/storage/el1/bundle/entry/resources/resfile/domainCaCert.
{
"network-security-config": {
"base-config": {
"trust-anchors": [
{
"certificates": "/data/storage/el1/bundle/entry/resources/resfile/appCaCert"
}
]
},
"domain-config": [
{
"domains": [
{
"include-subdomains": true,
"name": "example.com"
}
],
"trust-anchors": [
{
"certificates": "/data/storage/el1/bundle/entry/resources/resfile/domainCaCert"
}
]
}
]
}
}Network Kit also supports specifying the trusted CA path in the HTTPS request code via the caPath option:
httpRequest.request('EXAMPLE_URL', {
method: http.RequestMethod.POST,
header: { 'Content-Type': 'application/json' },
extraData: 'data to send',
expectDataType: http.HttpDataType.STRING,
connectTimeout: 60000,
caPath: '/data/storage/el1/bundle/entry/resources/resfile/domainCaCert'
}, (err, data) => { ... });Remote Communication Kit supports specifying the trusted CA path in code:
const caPath: rcp.CertificateAuthority = {
folderPath: '/data/storage/el1/bundle/entry/resources/resfile/appCaCert'
};
const securityConfig: rcp.SecurityConfiguration = {
remoteValidation: caPath
};
const sessionWithSecurityConfig = rcp.createSession({ requestConfiguration: { security: securityConfig } });Note: After the above configuration, Network Kit and Remote Communication Kit still trust system pre-installed CA certificates and user-installed CA certificates. To increase security, configure distrust of user-installed CA certificates.
For third-party libraries (e.g., curl), set the app-managed CA certificate path in code:
curl_easy_setopt(curl, CURLOPT_CAINFO, "/data/storage/el1/bundle/entry/resources/resfile/domainCaCert");Trust User-Installed CA Certificates
User-installed CA certificates have low trustworthiness. Except for the following scenarios, apps should not trust them:
Development and debugging — for packet capture to locate issues and test. User-installed CA certs are stored in /data/certificates/user_cacerts/{userid} (userid starts from 100). Production releases must not trust user-installed CAs.
Enterprise (2B) apps requiring corporate proxy — device must have CA cert installed via enterprise MDM or device admin, stored in /data/certificates/user_cacerts/0.
Configuring SSL Pinning (Certificate Pinning)
Apps default to trusting system pre-installed CA certificates. If a pre-installed CA issues an untrusted certificate, the app faces attack risk. For high-security apps (finance, banking), SSL Pinning can be configured to trust only the specified server certificate's public key.
Two configuration methods are supported. If the server domain is fixed, use static SSL Pinning; otherwise, use dynamic SSL Pinning.
Important considerations: SSL Pinning requires the server certificate's public key to remain unchanged. If the public key changes, the app's pinned key must be updated, otherwise network connections will fail. Always include at least one backup public key. An expiration time can be set for SSL Pinning. After expiration, the certificate is no longer pinned, helping prevent connection failures for unupdated apps when the server key changes. However, setting an expiration may allow attackers to bypass pinning. Developers must evaluate the trade-offs between security risks and SSL Pinning constraints. If the app already encrypts or signs sensitive data at the application layer, the security risk is lower.
1. Static SSL Pinning via 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="
}
]
}
}
]
}
}2. Dynamic SSL Pinning in Code
Network Kit:
certificatePinning: [
{
publicKeyHash: 'g8CsdcpyAKxmLoWFvMd2hC7ZDUy7L4E2NYOi1i8qEtE=',
hashAlgorithm: 'SHA-256'
}, {
publicKeyHash: 'MGFiY2UyMDk5ZjEyMzI3MWQ4MDMyY2E4ODEzMmY3EtE=',
hashAlgorithm: 'SHA-256'
}
]Remote Communication Kit:
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);Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
HarmonyOS Developer Technology
HarmonyOS developers provide key technology analysis, version updates, Codelabs practice, and event information for HarmonyOS. Welcome developers to join the HarmonyOS ecosystem and create infinite possibilities together!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
