silkimen / cordova-plugin-advanced-http

Cordova / Phonegap plugin for communicating with HTTP servers. Allows for SSL pinning!
MIT License
400 stars 319 forks source link

[Feature] key pinning #234

Open afife opened 5 years ago

afife commented 5 years ago

Context / Challenge

CAs are required to replace misissued TLS certificates (e.g. organization name exceeding 64 characters, short serial number, etc) in less than 5 days. Replacing a certificate usually means the CA to reissue the certificate with the same subject public key and corrected fields and revoke the previous certificate.

In this period, sysadmins have to replace the old certificate by the new one (no need to generate new key pairs and/or CSR as the public key is the same).

If an app is doing certificate pinning, it has also to be updated with the new certificate (the certificate and respective certificate fingerprint is different). Depending on the app store program and the test complexity, the release cycle may take over 1 week and the roll out to end users is a gradual and slow process.

Therefore, this 5-days window is nearly impossible to meet without significant outages if doing certificate pinning.

Solution In order to avoid the need for new app releases whenever a TLS certificate is replaced, this library should also support public key pinning.

Instead of pinning the certificate fingerprint, one would pin the fingerprint of the Subject Public Key Info (SPKI). The SPKI is the binary structure (DER encoded) of the public key and is present in several files: PKCS#8 key file, CSR and certificate.

Here follows the OpenSSL commands to obtain the fingerprint:


# Get public key fingerprint from a PKCS#8 file with the key pair
openssl rsa -in mytls.key -passin pass:myStr0ngP@s§w0rd -pubout -outform DER | openssl dgst -sha256

# Get public key fingerprint from the CSR (PEM format)
openssl req -in mytls.csr -pubkey -noout | openssl rsa -pubin -outform DER | openssl dgst -sha256

# Get public key fingerprint from the certificate (PEM format)
openssl x509 -in mytls.cer -noout -pubkey | openssl rsa -pubin -outform DER | openssl dgst -sha256

Further references

CodeWithOz commented 4 years ago

Hi @silkimen , any hope of this feature coming any time soon?

PauMateu commented 3 years ago

Hi! @silkimen , This feature could be very useful as we won't have to force a binary update to the users when the certificate is updated or renewed. Any hope this feature will be coming soon?

Thanks!

cremfert commented 3 years ago

I found a solution to this: just do not call setServerTrustMode so that the default validation of IOS is used. As this plugin uses AFNetworking in the background you can now install TrustKit (https://github.com/datatheorem/TrustKit) and configure it in Info.plist. Configure TrustKit to use auto-swizzling as described here (https://github.com/datatheorem/TrustKit/blob/master/docs/getting-started.md#consider-leveraging-auto-swizzling-for-simple-apps). Now, TrustKit intercepts all calls from AFNetworking (and hence this plugin) and checks the public keys.

iamitksharma commented 3 years ago

I tired to do SSL pinning with the help of Public key but getting pinning error. Code used : // enable SSL pinning cordova.plugin.http.setServerTrustMode('pinned', function() { console.log('success!'); }, function() { console.log('error :('); });

Does cordova-plugin-advanced-http support public key pinning i.e certificate directly downloaded from web application and using in capacitor application for SSL pinning?