Using the Objective-C gRPC library, how do I implement TLS certificate pinning?
Bonus question: how do I achieve this using GRPCcall2, and not the deprecated GRPCcall?
gRPC doesn't support TLS certificate pinning, but you can set the root certificate in GRPCMutableCallOptions
/**
* PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default
* root certificates.
*/
#property(copy, readwrite, nullable) NSString *PEMRootCertificates;
https://github.com/grpc/grpc/blob/master/src/objective-c/GRPCClient/GRPCCallOptions.h#L331
Related
I'm trying to access a certain API and I have been provided with a smart card which contains the certificate that I'm supposed to use to establish a SSL connection with the said API. I'm trying to do this through a Delphi appliction.
The following is the info of the certificate:
The certificate used to establish a secure connection is stored on a
smart card and it can be accessed from the PKI Applet using PKSC#11
API. The certificate is loaded in the slot / token structure on the
PKI Applet. After the certificate is extracted from the smart card (in
DER format) it can be used as a standard X.509 certificate for TLS/SSL
and HTTPS protocols.
I'm able to extract the certificate (via pkcs11CertificateStorage tool from SecureBlackbox) but I'm hvaing trouble using it for a SSL connection with Delphi.
Here's a simplified version of what I'm doing to attach the certificate to the request (using ipWorks REST component):
var
CertStorage: TsbxCertificateStorage;
ipwREST1: TipwREST;
// ...
CertStorage.Open('pkcs11://user:' + Pin + '#/' + StorageFilename + '?slot=0'+ RO);
ipwREST1.SSLCertEncodedB := CertStorage.Certificates[0].Bytes;
ipwREST1.Get('https://...');
The error that I get from the REST component:
273: Could not acquire security credentials: error 0x8009030E
Which led me to the error explanation by the component developer:
When using a certificate for client authentication, ensure the certificate's private keys are accessible. The certificate in the Windows certificate store must contain the corresponding private keys, and be marked as exportable.
and I'm not sure how to interpret this.
I've tried saving the certificate in a file, using openSSL to convert to PEM and attaching it in other ways but with no success.
I feel like I'm missing something in my approach. Any help would be appreciated, thanks.
Anyone please explain the role of SSL pinning and App transport security.
I read that SSLpinning is used to ensure that the app communicates only with the designated server itself
With the release of the iOS 9, the App Transport Security library was also introduced. By default, ATS denies all insecure connections which do not use at least the TLS 1.2 protocol. The TLS protocol is a replacement for the SSL protocol, but still, both of them are often referred to as SSL. With SSL pinning in mind, there is no difference between having TLS or SSL as the underlying implementation - the basic concept remains the same.
So my question is
1. If my server is using TLS 1.2 protocol, then enabling ATS is enough for security. No need of doing SSL Pinning in my app. Please confirm
2. If my server below TLS 1.2 protocol, then SSL pinning is the best way to avoid insecure connections. Please confirm
Cert pinning makes sure your app is communicating with the correct server. Without Cert pinning I can set up an intercepting proxy to see all of the traffic flowing in and out of your app.
Pinning the cert makes sure I cannot do this as the app will only accept communications from the server the offers the correct pinned certificate.
then enabling ATS is enough for security
You can never have 'enough for security' but this part is contextual based on what your app is doing. If the endpoints and data your app processes is sensitive you should defiantly be cert pinning. I would argue you should always do it anyway as it is easy to do.
If my server below TLS 1.2 protocol, then SSL pinning is the best way to avoid insecure connections
This will cause problem with ATS, your server should really be supporting TLS 1.2 it is pretty ubiquitous now. You also need to make sure the cert is using at east SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256bit or greater Elliptic-Curve (ECC) key and you need to support one of these cyphers:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
This may look scare but in reality the above is pretty standard.
NOTE:
both of them are often referred to as SSL
You are correct but this is a bad habit. They might do the same thing but they do it in a different way. SSL is SSL and TLS is TLS, they are different.
NOTE 2:
If you do use cert pinning consider using public key pinning or CA cert pinning.
https://infinum.co/the-capsized-eight/how-to-make-your-ios-apps-more-secure-with-ssl-pinning
"With the release of the iOS 9, the App Transport Security library was also introduced. By default, ATS denies all insecure connections which do not use at least the TLS 1.2 protocol. The TLS protocol is a replacement for the SSL protocol, but still, both of them are often referred to as SSL. With SSL pinning in mind, there is no difference between having TLS or SSL as the underlying implementation - the basic concept remains the same.
We're attempting to follow the Apple docs for using your own certificate authority (CA):
While a self-signed certificate is a reasonable approach during
development, there is a better way: create your own certificate
authority ... and have it issue a certificate for your test server.
You can then ... hard-wire your certificate authority's root
certificate into your app
I haven't been able to figure out how to hard wire the CA root cert using Swift. The paper mentions an approach but I haven't been able to translate this into Swift code:
Get a copy of the remote peer's certificate ...
Get the server
certificate from the trust object (pass an index of 0 to
SecTrustGetCertificateAtIndex)
Get the data for that server
certificate (SecCertificateCopyData)
Compare this to the certificate
data you got in step 1; if they match, you're talking to the correct
peer
How can you do this via Swift?
You hear a lot about how you can use SSL pinning to increase the security in your app. I was always under the assumption that SSL pinning is only helpful if you use a self-signed cert. Are there benefits of SSL pinning when using a cert signed by a cert authority, or does the CA make that unnecessary?
SSL/TLS has some issues, and the root of those issues is the CA system. By default, your browser trusts a bunch of CAs. Other than a few basic checks such as hostname, etc, the real power of the SSL comes from the verification of the certificate via the intermediaries until you get to a certificate that you trust.
Certificate pinning specifies that you will only trust a given certificate for a given web site. That is to say, if you received a "valid" certificate signed by a different CA (even if you trusted that CA) you would not trust it for this site.
In short, the fact that the CA has signed a cert does not reduce the need for certificate pinning.
For example: Companies sometimes intercept SSL. To do this, they actually serve the client a different SSL certificate that is valid for the host that the client is trying to access. Because they can insert any certificate into the trusted root (windows via GPO) they can insert their certificate instead of the actual one issued by the host. In this scenario, the SSL interception is transparent to the user. They are still being issued a "valid" certificate that is signed by a CA they trust (whether they know it or not). If you had been using certificate pinning, the new cert would be rejected.
There are cons to certificate pinning, mostly around the management of the cert as it expires etc.
See this link for more info.
I have an iPhone app , that needs to make secure connection to my webservice
I have a CA which i created and want to add to the app, so that it creates the connection and authenticates my server
I am using restkit 0.20.3 to make the requests.
How do i configure the AFHHTTPClient to trust my certificate ?
Only adding the your URL as https:// formate will do because your information will be encrypted based on the SSL certificate
In ASIHttpRequest Client certificates support
If your server requires the use of client certificates, as of v1.8 it is now possible to send them with your request.
// Will send the certificate attached to the identity (identity is a SecIdentityRef)
[request setClientCertificateIdentity:identity];
// Add an additional certificate (where cert is a SecCertificateRef)
[request setClientCertificates:[NSArray arrayWithObject:(id)cert]];
There is a helper function in ClientCertificateTests.m in the iPhone / iPad sample app that can create a SecIdentityRef from PKCS12 data (this function only works on iOS).
and look here for more info about handling the self signed certificate at iOS end:
Use a self-signed ssl certificate in an iphone app
iPhone: install certificate for SSL connection