Introduction
This article describes how to configure SmartBrowser to trust self-signed certificates and manage SSL certificate errors. Two approaches are available: enabling the “trust anything” option, or adding specific certificates to the configuration.
Method 1: Trust Any Certificate (Quick Setup)
Warning: This method trusts ALL certificates, including invalid or malicious ones. Use only in development or highly controlled environments.
Configuration
Add the following to the smartconfig.json:
{
"certificates": {
"allowAny": true
}
}
When allowAny is set to true, SmartBrowser automatically trusts any SSL certificate presented by any server, regardless of validity, expiration, or trust chain issues.
Security Note: This bypasses all SSL security checks and should never be used in production environments where security is a concern.
Method 2: Configure Specific Certificates (Recommended)
This method allows specific certificates to be trusted while maintaining security for all others. Certificates can be configured using multiple methods outlined below.
2.1 Using PEM Certificates
Add certificates in PEM format directly to the configuration file. This option is useful when the full certificate text is available.
Configuration:
{
"certificates": {
"certificates": [
[
"—–BEGIN CERTIFICATE—–",
"MIIDXTCCAkWgAwIBAgIJAKL7wQ8O3u3tMA0GCSqGSIb3DQEBCQUAMEUxCzAJBgNV",
"BAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX",
"aWRnaXRzIFB0eSBMdGQwHhcNMTcwODI3MjM1MjU5WhcNMjcwODI1MjM1MjU5WjBF",
"MQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50",
"ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB",
"CgKCAQEAyMEdSs1aIZyQVt2jW8VaUkRtxa2QdSYV30kDg46YDCuY1mL8oUrjB3C",
"—–END CERTIFICATE—–"
]
]
}
}
How it works:
- Each certificate is represented as an array of strings
- Each string is a line from the PEM certificate
- The system automatically combines these lines with newlines
To get a PEM certificate:
# From a website
openssl s_client -showcerts -connect example.com:443 /dev/null | openssl x509 -outform PEM > cert.pem
# From a certificate file
openssl x509 -in cert.crt -outform PEM -out cert.pem
2.2 Using Certificate Fingerprints
Fingerprints are unique identifiers for certificates. You can use either SHA-1 or SHA-256 fingerprints.
Configuration:
{
"certificates": {
"fingerprints_SHA1": [
"A1:B2:C3:D4:E5:F6:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12"
],
"fingerprints_SHA256": [
"CC C1 25 F2 BF 5B A9 7B 21 DF 9F DC 2B 6E 76 C5 CB FD 7B F2 AC 68 BF FD 52 8E 6E 69 4E CE 19 0B"
]
}
}
Notes:
- Fingerprints can include spaces, colons, or be continuous (they are automatically normalized)
- SHA-256 fingerprints are recommended for better security
- SHA-1 fingerprints are supported but deprecated
To obtain a certificate fingerprint:
# SHA-256 fingerprint (recommended)
openssl x509 -in cert.pem -fingerprint -sha256 -noout | cut -d'=' -f2 | tr -d ':'
# From a website directly
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -fingerprint -sha256 -noout | cut -d'=' -f2
2.3 Using Certificate Serial Numbers
Certificates can be trusted by their serial number (in hexadecimal format).
Configuration:
{
"certificates": {
"serialNumbers": [
"A1B2C3D4E5F67890"
]
}
}
To obtain a certificate serial number:
openssl x509 -in cert.pem -noout -serial | cut -d'=' -f2
2.4 Using Certificate Files
Certificate files stored on the device filesystem can be referenced.
Configuration:
{
"certificates": {
"files": [
"/sdcard/certificates/my-cert.pem",
"/data/data/com.staylinked.smartbrowser/files/certs/server-cert.crt"
]
}
}
How it works:
- The system reads each file and extracts the SHA-256 fingerprint
- The fingerprint is automatically added to the trusted list
- Files must be accessible by the application
File format: Certificates can be in PEM or DER format (PEM is recommended).
Method 3: SSL Error Handling Flags
SmartBrowser can be configured to ignore specific types of SSL errors. This is useful when certificates have minor issues but the certificate itself should still be verified.
Configuration:
{
"sslErrorHandling": 255
}
The sslErrorHandling value is a bitmask that controls which SSL errors to ignore. Details are shown in the table below.
| Flag Value | Error Type | Description |
| 0x01 | SSL_NOTYETVALID | Certificate not yet valid (future date) |
| 0x02 | SSL_EXPIRED | Certificate has expired |
| 0x04 | SSL_IDMISMATCH | Hostname mismatch |
| 0x08 | SSL_UNTRUSTED | Certificate authority not trusted |
| 0x10 | SSL_DATE_INVALID | Certificate date is invalid |
| 0x20 | SSL_INVALID | Certificate is invalid |
Common values:
- 0 (or SSL_ERROR_HANDLING_NONE) – Don't ignore any errors (strict)
- 255 (or SSL_ERROR_HANDLING_ALL) – Ignore all SSL errors
- 15 (0x0F) – Ignore common errors (not yet valid, expired, hostname mismatch, untrusted)
Example – Ignore expired and hostname mismatch:
{
"sslErrorHandling": 6
}
This is calculated as: 0x02 (EXPIRED) + 0x04 (IDMISMATCH) = 6
Note: Even with error handling flags set, certificates must still pass the certificate checker (via certificates configuration) unless allowAny is true.
Configuration File Location
The certificate configuration should be added to your smartconfig.json file. This file is typically located at:
- Assets: app/src/main/assets/config/smartconfig.json (default/bundled config)
- Device: /sdcard/smartbrowser/config/smartconfig.json (user config, overrides bundled)
When deploying via SBP packages, the configuration is typically included in the package and merged with existing settings.
Examples
Example 1: Development Environment – Trust Everything
For development environments where quick testing with self-signed certificates is required:
{
"certificates": {
"allowAny": true
},
"sslErrorHandling": 255
}
Example 2: Production – Trust Specific Self-Signed Certificate
For production use with a specific self-signed certificate:
{
"certificates": {
"allowAny": false,
"fingerprints_SHA256": [
"CC C1 25 F2 BF 5B A9 7B 21 DF 9F DC 2B 6E 76 C5 CB FD 7B F2 AC 68 BF FD 52 8E 6E 69 4E CE 19 0B"
],
"certificates": [
[
"—–BEGIN CERTIFICATE—–",
"MIIDXTCCAkWgAwIBAgIJAKL7wQ8O3u3tMA0GCSqGSIb3DQEBCQUAMEUxCzAJBgNV",
"… (rest of certificate lines) …",
"—–END CERTIFICATE—–"
]
]
},
"sslErrorHandling": 0
}
Example 3: Internal CA Certificate
When using an internal Certificate Authority:
{
"certificates": {
"allowAny": false,
"files": [
"/sdcard/certificates/internal-ca.pem"
],
"fingerprints_SHA256": [
"AA BB CC DD EE FF 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 11 22 33 44 55 66 77 88 99 AA BB"
]
},
"sslErrorHandling": 4
}
This configuration:
- Loads the CA certificate from a file
- Also trusts certificates with the specified SHA-256 fingerprint
- Allows hostname mismatches (useful for internal domains)
Example 4: Multiple Certificates with Error Handling
Trust multiple certificates while allowing some common errors:
{
"certificates": {
"allowAny": false,
"fingerprints_SHA256": [
"CC C1 25 F2 BF 5B A9 7B 21 DF 9F DC 2B 6E 76 C5 CB FD 7B F2 AC 68 BF FD 52 8E 6E 69 4E CE 19 0B",
"AA BB CC DD EE FF 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 11 22 33 44 55 66 77 88 99 AA BB"
],
"serialNumbers": [
"A1B2C3D4E5F67890",
"1234567890ABCDEF"
]
},
"sslErrorHandling": 15
}
This configuration:
- Trusts certificates matching any of the SHA-256 fingerprints
- Trusts certificates with the specified serial numbers
- Ignores common SSL errors (not yet valid, expired, hostname mismatch, untrusted)
How It Works
- Certificate Checker (OverrideCertChecker):
- When an SSL error occurs, the browser first checks if the certificate is in the trusted list
- It compares the certificate against fingerprints, serial numbers, and PEM certificates
- If allowAny is true, all certificates are automatically trusted
- SSL Error Handler (BaseBrowser.onReceivedSslError):
- If the certificate passes the certificate checker, the connection proceeds
- If not, the sslErrorHandling flags are checked
- If the error type matches a flag, the connection proceeds
- Otherwise, the SSL error is passed to the default handler (connection fails)
- Priority:
- Certificate checker (allowAny or specific certificates) takes precedence
- SSL error handling flags are checked if certificate checker doesn't match
- If neither matches, the connection is rejected
Troubleshooting
Certificate Not Being Trusted
- Verify the fingerprint: Make sure you're using the correct fingerprint format
openssl x509 -in cert.pem -fingerprint -sha256 -noout
- Check file paths: If using files, ensure the file path is correct and accessible
- Verify PEM format: PEM certificates must include the —–BEGIN CERTIFICATE—– and —–END CERTIFICATE—– lines
- Check logs: Look for SSL error messages in the application logs to see what error is occurring
Common Issues
- Hostname mismatch: Add SSL_ERROR_HANDLING_IDMISMATCH (0x04) to sslErrorHandling or use the certificate fingerprint
- Expired certificate: Add SSL_ERROR_HANDLING_EXPIRED (0x02) to sslErrorHandling or use allowAny: true
- Untrusted CA: Add the CA certificate to the certificates array or use allowAny: true
Security Best Practices
- Avoid allowAny: true in production – Only use in development or highly controlled environments
- Use SHA-256 fingerprints – More secure than SHA-1
- Use specific certificates – Only trust the certificates actually required
- Combine methods – Use fingerprints for quick setup, PEM certificates for full certificate chain support
- Monitor certificate expiration – Update fingerprints or certificates before they expire
- Use file-based certificates – For easier management and updates without modifying JSON
Additional Notes
- Certificate configurations are loaded when the application starts or when configuration is reloaded
- Changes to smartconfig.json require an application restart or configuration reload to take effect
- Certificate files referenced in the files array are read at startup
- PEM certificates in the certificates array are parsed and their fingerprints are automatically added to the trusted list
Quick Reference
Trust all certificates:
{ "certificates": { "allowAny": true } }
Trust by SHA-256 fingerprint:
{ "certificates": { "fingerprints_SHA256": ["AA:BB:CC:…"] } }
Trust by PEM certificate:
{ "certificates": { "certificates": [[ "—–BEGIN CERTIFICATE—–", "…", "—–END CERTIFICATE—–" ]] } }
Ignore all SSL errors:
{ "sslErrorHandling": 255 }
Ignore expired and hostname mismatch:
{ "sslErrorHandling": 6 }
Share the post "SmartBrowser SSL Certificates Configuration"