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?
Related
I can't find good information regarding certificate pinning in iOS and Amazon Certificate Manager.
They recommend you don't pin against an ACM certificate.
https://docs.aws.amazon.com/acm/latest/userguide/acm-bestpractices.html#best-practices-pinning
We recommend that your application not pin an ACM Certificate
The reason they don't recommend it is that:
To renew a certificate, ACM generates a new public-private key pair.
Instead, they recommend:
If you're using a public certificate, pin your application to all available Amazon root certificates.
I understand why not to pin to an ACM Certificate - because you will have to release updates with new certificates risking possible bricking of clients. You also can't pin against the public key because it will change.
What I don't understand is how pinning against only the root certificates is ok? Will it still prevent man in the middle attacks? How is this more secure?
Can someone explain it better?
It would not be more secured to pin against the root certificate. I think what the Amazon documentation trying to recommend is a way that would not break your network connection in the case that when the certificate expires and renews.
Here's the quote from this website explaining the different kinds of certificate pinning:
https://carvesystems.com/news/cert_pin/
Leaf Cert: A leaf cert is the top level cert in a certificate chain.
Pinning a leaf certs brings us to almost complete certainty that the
certificate matches. However, if you cycle your leaf certs often,
updates need to roll out fairly frequently to make sure your
customer’s app continues to work.
Intermediate Cert: The intermediate cert lives between the leaf and
root cert. In this case, pinning against the intermediate cert, you’re
putting your trust in the intermediate certificate authority.
Therefore, you can update your server’s leaf cert more often, as the
validation of certs occurs on the intermediate cert.
Root Cert: Finally, the root cert comes from the trusted certificate
authority. Pinning the root cert alone puts trust in the root cert
authority, as well as all intermediaries that the root cert authority
trusts.
Hope this helps
My app contains a public certificate (cert A) that is used for https connection. It works by using this method URLSession:didReceiveChallenge:completionHandler:
But I would like to verify certificate (cert B) that is downloaded with additional data from server. Cert A is CA for cert B.
I cant find any solutions.
I use X.509 standard. (cert A is .pfx and cert B is .der)
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 am developing mdm server and I have a problem with one of enrollment steps. The problem is scep step. I implement a scep server which handles Device CACert request and sends our server certificate in der format. After that, device sends encrypted and signed csr. But I can not verify signature of message. I think device creates a self-signed-certificate and sign message with it. We think that because signature certificate's common name is changing each "PKIOperation" request. But we must verify this signature because of security.
For example in each 3 enrollment request, certificate of csr signature changes. Their common names are:
CN=6E4F65AD-1E64-4E4D-A96E-2039EB140041
CN=2E33C2CC-14B8-47AC-938B-DCC7F8DA8715
CN=6817ED48-AB79-4FF0-A1A9-42C2AC303672
Note: The other steps of enrollment device sign messages with proper certificate and I can verify them. Only scep PKIOperation request is my problem. Is there any profile flag to set or something to solve this problem?
I may be wrong in some details, because I touched this about two years ago.
However, as I remember it's part of a protocol
If you take a look at SCEP draft: https://datatracker.ietf.org/doc/html/draft-nourse-scep-23#page-30 you will see this:
When building a pkiMessage, clients MUST have a certificate to sign
the PKCS#7 [RFC2315] signed-data (because PKCS#7 [RFC2315] requires
it). Clients MUST either use an existing certificate, or create a
self-signed certificate (see Section 2.3).
If the requester does not have an appropriate existing
certificate, then a locally generated self-signed certificate
MUST be used instead. The self-signed certificate MUST use the
same subject name as in the PKCS#10 request.
However, I was under impression that iOS device uses certificate/private keys which are built into the device. And this certificate is signed using Apple certs. And actually, as I remember they had exactly the format of CN, which you shown.
So, generally speaking it's ok if device uses self-signed certificate for first communication to the SCEP server (PKIOperation) and uses a certificate issued by your CA later on.
The Application i am working on needs to connect to a webservice over https, The certificate is trusted and valid.
I have used NSURLConnection is previous projects to use soap over http
Can anybody please point the difference between the two above mentioned scenarios,
I also need to understand what exactly happens when connecting over https, is the certificate stored automatically on the device, how does ssl handshake happen.
Any Pointers in this direction will be really helpful.
Regards,
Ishan
I need some clarification. Is the certificate signed by Apple for use with notifications or is it signed by an SSL root certificate authority (like VeriSign)?
Apple signed certificates are only to be used with WebServer to Apple Server communications like the Apple Push Notification Service. They are not intended for iOS device to WebServer.
A SSL certificate signed by a SSL root certificate authority should just work.
I think you are looking for an HTTP over SSL/TLS primer. So, here it goes.
HTTP is an unencrypted channel. The request and response are in a plain text data stream. HTTPS is an encrypted channel. The request and response are in a data stream encrypted using a shared master key. The magic of SSL/TLS is how this encrypted channel is created.
First, the client and server say hello to each other (in a clear channel).
Next, the client downloads the server's public certificate (in a clear channel).
At this point, the client has some work to do. It needs to verify the certificate. It needs to know that it understands the certificate, that the date range is valid, that the certificate is signed by a trusted certificate authority, and that the certificate has not been revoked.
Now, the client knows that it can trust the server.
Next, It sends a few short messages encrypted with the public key of the server (which is in the server's public certificate). These messages can only be decrypted by the server's private key (which only the server knows about). These messages allow the client and the server to negotiate a master key.
Finally, the client and the server begin the normal HTTP request and response using the newly created encrypted channel.
I hope this is what you are looking for. For a more detailed description see: http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html
If the certificate was issued by a chain of certificate authorities whose root is trusted by Apple, then there is nothing to do. The iOS device will accept the certificate, as long as it is otherwise valid (ie not expired, not revoked, etc).
If the CA chain's root is not trusted by Apple, you will need to download the root's certificate to the phone. This can be done (I think) via the iPhone Configuration Utility. Enterprise provisioning scenarios undoubtedly support this also.