sslpinning-capacitor
v0.0.1
Published
Provides SSL pinning functionality for Capacitor apps, allowing secure HTTPS communication by validating server certificates using a known fingerprint or base64-encoded certificate.
Maintainers
Readme
sslpinning-capacitor
A comprehensive SSL certificate pinning plugin for Capacitor applications that provides secure HTTPS communication by validating server certificates against known SHA-256 fingerprints. This plugin helps prevent man-in-the-middle attacks and certificate authority compromises by ensuring your app only communicates with servers presenting expected certificates.
🔒 What is SSL Pinning?
SSL pinning is a security technique that hardcodes the expected SSL certificate fingerprint in your application. Instead of trusting any certificate signed by a trusted Certificate Authority (CA), your app validates that the server's certificate matches a specific fingerprint you've pre-configured. This provides an additional layer of security against:
- Man-in-the-middle attacks
- Compromised Certificate Authorities
- DNS hijacking
- Certificate substitution attacks
✨ Features
- Cross-platform support: iOS, Android, and Web (with fallback)
- SHA-256 fingerprint validation: Uses industry-standard SHA-256 hashing
- Multiple fingerprint support: Validate against multiple expected fingerprints
- Detailed certificate information: Get comprehensive certificate details
- Automatic HTTPS validation: Ensures URLs use HTTPS protocol
- Error handling: Comprehensive error reporting for debugging
- TypeScript support: Full type definitions included
📦 Installation
Using npm:
npm install sslpinning-capacitorUsing yarn:
yarn add sslpinning-capacitorSync with Capacitor:
npx cap sync🚀 Quick Start
1. Basic Usage
import { SSLPinning } from 'sslpinning-capacitor';
// Example: Validate Google's SSL certificate
const result = await SSLPinning.checkSSL({
url: 'https://www.google.com',
fingerprints: [
'AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99'
]
});
console.log('SSL Validation Result:', result);2. Multiple Fingerprints
// You can provide multiple fingerprints for redundancy
const result = await SSLPinning.checkSSL({
url: 'https://api.example.com',
fingerprints: [
'AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99',
'11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11'
]
});3. Error Handling
try {
const result = await SSLPinning.checkSSL({
url: 'https://api.example.com',
fingerprints: ['AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99']
});
if (result.fingerprintMatched) {
console.log('✅ SSL certificate is valid!');
console.log('Certificate Subject:', result.subject);
console.log('Certificate Issuer:', result.issuer);
console.log('Valid From:', result.validFrom);
console.log('Valid To:', result.validTo);
} else {
console.log('❌ SSL certificate validation failed!');
console.log('Expected fingerprints:', result.expectedFingerprints);
console.log('Actual fingerprint:', result.actualFingerprint);
}
} catch (error) {
console.error('SSL check failed:', error.message);
}🔧 How to Get Certificate Fingerprints
Method 1: Using OpenSSL (Command Line)
# Get certificate fingerprint from a server
openssl s_client -connect api.example.com:443 -servername api.example.com < /dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256Method 2: Using the Plugin's CLI Tool
The plugin includes a CLI tool for extracting fingerprints:
# Install the plugin globally or use npx
npx sslpinning-capacitor https://api.example.comMethod 3: Browser Developer Tools
- Open your browser's Developer Tools
- Go to the Security/Network tab
- Visit the HTTPS site
- Click on the certificate information
- Copy the SHA-256 fingerprint
📋 API Reference
Main interface for the SSLPinning plugin Defines the contract that all platform implementations (iOS, Android, Web) must adhere to
checkSSL(...)
checkSSL(options: SSLCheckOptions) => Promise<SSLCheckResult>Performs SSL certificate pinning validation
| Param | Type | Description |
| ------------- | ----------------------------------------------------------- | ----------------------------------------- |
| options | SSLCheckOptions | - Configuration options for the SSL check |
Returns: Promise<SSLCheckResult>
Type Aliases
SSLCheckResult
{ /** * Certificate subject (entity the certificate is issued to) * @platform Android / subject?: string; /* * Certificate authority that issued the certificate / issuer?: string; /* * Certificate validity start date * @platform Android / validFrom?: string; /* * Certificate validity end date * @platform Android / validTo?: string; /* * Expected fingerprints provided in the options / expectedFingerprints?: string[]; /* * Actual certificate fingerprint from the server / actualFingerprint?: string; /* * Whether the actual fingerprint matches any expected fingerprint / fingerprintMatched?: boolean; /* * Error message if certificate check failed */ error?: string; }
SSLCheckOptions
{ /** * Target server URL for SSL certificate validation / url: string; /* * Expected certificate fingerprints (SHA-256 hashes) */ fingerprints: string[]; }
🛠️ Platform Support
| Platform | Status | Notes | |----------|--------|-------| | iOS | ✅ Supported | Full SSL pinning implementation | | Android | ✅ Supported | Full SSL pinning implementation | | Web | ⚠️ Limited | Throws unimplemented error (use server-side validation) |
🔍 Response Examples
Successful Validation
{
"subject": "CN=www.google.com, O=Google LLC, L=Mountain View, ST=California, C=US",
"issuer": "CN=GTS CA 1C3, O=Google Trust Services LLC, C=US",
"validFrom": "Mon Dec 16 15:00:00 UTC 2024",
"validTo": "Tue Mar 18 14:59:59 UTC 2025",
"expectedFingerprints": [
"AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
],
"actualFingerprint": "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99",
"fingerprintMatched": true
}Failed Validation
{
"expectedFingerprints": [
"AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
],
"actualFingerprint": "11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11",
"fingerprintMatched": false,
"error": "Certificate fingerprint mismatch"
}Error Response
{
"error": "URL is not HTTPS"
}🏗️ Integration Examples
React/Vue/Angular Integration
// Create a service for SSL validation
class SSLValidationService {
async validateServer(url: string, fingerprints: string[]): Promise<boolean> {
try {
const result = await SSLPinning.checkSSL({ url, fingerprints });
return result.fingerprintMatched || false;
} catch (error) {
console.error('SSL validation failed:', error);
return false;
}
}
}
// Usage in your app
const sslService = new SSLValidationService();
const isValid = await sslService.validateServer(
'https://api.example.com',
['AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99']
);HTTP Interceptor Pattern
// Intercept HTTP requests and validate SSL
class SSLInterceptor {
async intercept(request: any): Promise<any> {
// Validate SSL before making the request
const sslResult = await SSLPinning.checkSSL({
url: request.url,
fingerprints: ['AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99']
});
if (!sslResult.fingerprintMatched) {
throw new Error('SSL certificate validation failed');
}
// Proceed with the request
return request;
}
}🔒 Security Best Practices
- Store fingerprints securely: Don't hardcode fingerprints in your source code
- Use multiple fingerprints: Provide backup fingerprints for certificate rotation
- Regular updates: Update fingerprints when certificates are renewed
- Monitor certificate expiration: Track certificate validity dates
- Fallback strategy: Have a plan for when certificates change
🐛 Troubleshooting
Common Issues
"URL is not HTTPS" error
- Ensure the URL starts with
https:// - Check for typos in the URL
- Ensure the URL starts with
"Certificate check failed" error
- Verify the server is accessible
- Check network connectivity
- Ensure the server has a valid SSL certificate
Fingerprint mismatch
- Verify the fingerprint is correct
- Check if the certificate has been renewed
- Update the fingerprint if necessary
Debug Mode
Enable debug logging to troubleshoot issues:
// The plugin automatically logs debug information on iOS
// For Android, check logcat for detailed error messages📄 License
This software implements SSL (Secure Sockets Layer) pinning as a security measure. It is provided under the MIT License. The SSL pinning code included in this project is provided "as is" without any warranty, express or implied.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📞 Support
If you encounter any issues or have questions, please:
- Check the troubleshooting section
- Search existing issues
- Create a new issue with detailed information
Made with ❤️ for secure mobile applications
