How to gather/verify certificate data with limited information (Issuer, Serial, CN) - certificate

I've been included in an analysis project or "cleaning up" of information which includes fields from certificates. I don't know how to access the actual certificates. I'd like to learn as much as I can about how/what can be verified in relation to a certificate. (I'm not doing security work, I just need to read the information.)
I have several spreadsheets with information including certificate data, all different sources with different fields. I'm trying to consolidate this information into a single table with as much verified as possible. Most records have Control Name, Serial Number, URL, etc., but based on the inconsistencies throughout other fields I think wrong or incomplete data has been added.
For instance, I'd like to verify that the expiration date on a spreadsheet is what is actually on the certificate. It also looks like one of the spreadsheets converted long serial numbers into a numeric data type, truncating(all 0's) the last half of the SN. Is there a way to look up all of a CN's certificates issued by a CA?
I'm very new to this, any tips would be appreciated.
Thank you

There is no general, public way I know of.
However, you might be able to get in touch with some CAs and do a research cooperation, but I doubt it. Handing out certificates to somebody else could be a privacy concern. And there's no chance you'll get certificates from all the CAs out there.
What you can do is obtain the certificates when they are used for publicly available services. For example if a certificate is issued to mail.example.com you could try to establish a TLS session to the host. You may have to try different ports, and maybe you are lucky and the host presents the certificate you are looking for.

Related

Concept of Digital Signatures for a specific scenario

My company develops an ERP for hospitals and because of some legislation changes throughout this weekend I've been reading a lot on digital signature because I need to solve the following scenario:
Each doctor will receive from the ministry of health a certificate (so there's no escape from it... government said so...) and all of his reports sent/stored in digital format must be signed with this certificate.
The certificates will be valid for one year. Each year upon renewing of the medical license, the certificate will be renewed.
Our main concern here is guaranteeing the source of the document (the sender is who he claims to be) but we must also make "impossible" (or at least infeasible) to change the content of the document (or at least that if it changes, we have to be able to tell that a modification occurred) and to "extracted and replicated" the signature...
My question is: how do I deal with this whole thing? What should I do?
PS: In your answer pls consider that:
The documents will persist far beyond the certificate lifetime.
The certificate might have been revoked. Documents signed before the revoke must still be valid
How a 3rd party would verify the integrity of the information (document + certification)
Is there not a security principle which states that information signed with a expired certificate is invalid or something?
I'm really new to this area and I might be asking the wrong question...
In brief, the document must be signed using CAdES, PAdES or XAdES (depending on data format) standard, where timestamping is applied and other measures are taken. These standards were designed specifically for tasks similar to yours so they address your concerns. I recommend that you read some articles about those formats. Unfortunately I don't have a link to share with you right now, but you can find a lot based on those abbreviations.
CAdES is based on PKCS#7/CMS (certificate-based signing of generic data with wrapping signatures) .
PAdES is an extension of PDF signing and is used specifically for PDF documents.
XAdES is similar to CAdES and can be used to sign XML documents and (more rarely) binary data.
[Disclosure: I work for CoSign by ARX.]
Your situation is common. You're raising a number of questions. My answers:
all of his reports sent/stored in digital format must be signed with this certificate.
You can digitally sign anything (any bundle of bits). The real issue is how can the recipient or auditor easily verify that the document:
was not modified since it was signed (integrity)
was signed by the right person (identity)
was signed with the right intent (signer's statement)
Machine readable data, eg form data, intermediate data, etc.
Signing: For info that is designed to be later machine-read (eg a form submission), store the info in XML and sign it using the XML Signing Standard: XAdES The CoSign Signature API (SAPI) directly supports signing XML docs.
Verifying There are many on-line XML digital signature verification services, Google for them. The SAPI api also supports verifying XML docs.
Human readable documents
Signing: For a "final" document that will be read by humans (but is stored digitally, can be included in searches, etc), PDF documents are the way to go. The PDF format supports digital signatures very well. There are many ways to add digital signatures to PDF documents. For developers, the CoSign Signature Web Agent is a web service (HTTPS + XML parameter document) that handles all the UI issues of signing.
Verifying: The most common way to verify the digital signatures of a pdf is to use the free Adobe Reader. (Not the expensive Adobe Acrobat.) Adobe Reader knows how to check the validity of the digital signatures and then tells the reader/signer/auditor that the signature is valid, the document was not changed since signed, etc.
Your other questions:
The documents will persist far beyond the certificate lifetime.
Yes, that is fine. Just like a "wet signature," once you've validly digitally signed a document, that document remains signed by you. -- Even if your signing certificate later expires. As part of the verification process, the date of signing is compared with the valid dates on the certificate.
The certificate might have been revoked. Documents signed before the revoke must still be valid
Yes, that is how standard digital signatures work. Even if a certificate is revoked, documents signed while the certificate was valid will remain signed. Because date/timestamps play such an important part of the validation process, there are 3rd party timestamping services available. But they are not used for most digital signatures. Instead, create explicit management procedures to make sure that the time server is properly setup with NTP to a good source and that the system is regularly checked and verified.
CoSign signs using a tamper-proof hw device. Its clock is synched using NTP.
How a 3rd party would verify the integrity of the information (document + certification)
As I discuss above, the whole verification question is important. That's why I recommend using XML or PDF as your document types. You could, for example, digitally sign your own system's internal data structure used to represent information. In this case the digital signature would be carried in a separate data structure. This is the "external signature" scenario. It all works fine, except that an auditor would need to either build his own sw to validate or trust that your sw is doing the validation properly. A better choice is to use a format that directly supports digital signatures and which can be easily verified.
Is there not a security principle which states that information signed with a expired certificate is invalid or something?
A proper digital signature system won't allow an expired certificate to be used to sign anything. Once something is signed, using a certificate that was valid at time of signing, it stays signed unless the document is subsequently changed.
I'm really new to this area and I might be asking the wrong question...
Other questions to ask: how do you add the signer's graphical signature to the document (XML or PDF)--people expect to see it. And how do you manage/administer the certificates? Server based signing is a good solution for this. Remember that certificates should not be stored in sw for any production systems. Instead, a Secure Signature Creation Device (something hw based) must be used.
You will also need to read the Baseline Profiles where there is a profile for long-term signatures.
There is a profile for each of the formats already mentioned by Eugene.
For example, if your document is PDF, you may use PAdES signatures and the LTA-Level specified in "PAdES Baseline Profile" document.
All of these documents are ETSI standards you can search for at: http://pda.etsi.org/pda/queryform.asp

iPhone App with a Server Backend - How to ensure all access is from the iPhone app only?

I don't mind so much about pirating etcetera, but I want to ensure that the backend (Rails based) isn't open to automated services that could DOS it etc. Therefore I'd like to simply ensure that all access to the backend (which will be a few REST queries to GET and PUT data) will be via a valid iPhone application, and not some script running on a machine.
I want to avoid the use of accounts so that the user experience is seamless.
My first intention is to hash the UDID and a secret together, and provide that (and the UDID) over a HTTPS connection to the server. This will either allow an authenticated session to be created or return an error.
If eavesdropped, then an attacker could take the hash and replay it, leaving this scheme open to replay attacks. However shouldn't the HTTPS connection protect me against eavesdropping?
Thanks!
Like bpapa says, it can be spoofed, but then, like you say, you aren't worried about that so much as anybody coming along and just sending a thousand requests to your server in a row, and your server having to process each one.
Your idea of the hash is a good start. From there, you could also append the current timestamp to the pre-hashed value, and send that along as well. If the given timestamp is more than 1 day different from the server's current time, disallow access. This stops replay attacks for more than a day later anyway.
Another option would be to use a nonce. Anybody can request a nonce from your server, but then the device has to append that to the pre-hash data before sending the hash to the server. Generated nonces would have to be stored, or, could simply be the server's current timestamp. The device then has to append the server's timestamp instead of its own timestamp to the pre-hashed data, allowing for a much shorter period than a full day for a replay attack to occur.
Use SSL with client certificate. Have a private key in your client and issue a certificate for it, and your web server can require this client cert to be present in order for the sessions to proceed.
I can't give code details for Rails, but architecture-wise it's the most secure thing to do, even though might be a bit overkill. SSL with certificates is a standard industry solution and libraries exist for both the iPhone/client end and server end, so you don't have to invent anything or implement much, just get them to work nicely together.
You could also consider HMAC, like HMAC-SHA1, which is basically a standardization of the hashes stuff that other people here talk about. If you added nonces to it, you'd also be safe against replay attack. For an idea about how to implement HMAC-SHA1 with nonces, you could look at OAuth protocol (not the whole flow, but just how they tie nonce and other parameters together into an authenticated request).
There is no way to ensure it, since it can be spoofed.
If you really want to go this route (honestly, unless you're doing something really super mission critical here you are probably wasting your time), you could pass along the iPhone device token. Or maybe hash it and then pass it along. Of course, you have no way to validate it on the Server Side or anything, but if a bad guy really wants to take you down, here is roadblock #1 that he will have to deal with first.

Is this plan for preventing iPhone app client spoofing sound?

I'm designing an iPhone app that communicates with a server over HTTP.
I only want the app, not arbitrary HTTP clients, to be able to POST to certain URL's on the server. So I'll set up the server to only validate POSTs that include a secret token, and set up the app to include that secret token. All requests that include this token will be sent only over an HTTPS connection, so that it cannot be sniffed.
Do you see any flaws with this reasoning? For example, would it be possible to read the token out of the compiled app using "strings", a hex editor, etc? I wouldn't be storing this token in a .plist or other plain-text format, of course.
Suggestions for an alternate design are welcome.
In general, assuming that a determined attacker can't discover a key that is embedded in application on a device under his physical control (and, probably, that he owns anyway) is unwarranted. Look at all of the broken DRM schemes that relied on this assumption.
What really matters is who's trying to get the key, and what their incentive is. Sell a product aimed at a demographic that isn't eager to steal. Price your product so that it's cheaper to buy it than it is to discover the key. Provide good service to your customers. These are all marketing and legal issues, rather than technological.
If you do embed a key, use a method that requires each client to discover the key themselves, like requiring a different key for each client. You don't want a situation where one attacker can discover the key and publish it, granting everyone access.
The iPhone does provide the "KeyChain" API, which can help the application hide secrets from the device owner, for better or worse. But, anything is breakable.
The way I understand it, yes, the key could be retrieved from the app one way or another. It's almost impossible to hide something in the Objective-C runtime due to the very nature of it. To the best of my knowledge, only Omni have managed it with their serial numbers, apparently by keeping the critical code in C (Cocoa Insecurity).
It might be a lot of work (I've no idea how complex it is to implement), but you might want to consider using the push notifications to send an authentication key with a validity of one hour to the program every hour. This would largely offload the problem of verifying that it's your app to Apple.
I suggest to add some checksum (md5/sha1) based on the sent data and a secret key that your app and the server knows.
Applications can be disassembled so that they could find your key.
More information is needed to determine whether the approach is sound. It may be sound for one asset being protected and unsound for another, all based on the value of the asset and the cost if the asset is revealed.
Several earlier posters have alluded to the fact that anything on the device can be revealed by a determined attacker. So, the best you can do is determine valuable the asset is and put enough hurdles in the way of the attacker that the cost of the attack exceeds the value of the asset.
One could add to your scheme client-side certificates for the SSL. One could bury that cert and the key for the token deep in some obfuscated code. One could probably craft a scheme using public/private key cryptography to further obscure the token. One could implement a challenge/response protocol that has a time boxed response time wherein the server challenges the app and the app has X milliseconds to respond before it's disconnected.
The number and complexity of the hurdles all depend on the value of the asset.
Jack
You should look into the Entrust Technologies (www.entrust.com) product line for two-factor authentication tied to all sorts of specifics (e.g., device, IMEI, application serial number, user ID, etc.)

Store an encryption key in Keychain while application installation process

I need my application to use client's phone-number to generate unique ID for my web-service. Of course a phone-number is unique, but it must be secured. So it can be implemented with symmetric encryption (asymmetric will be later, because leak of resources), but I do not know where to store a encryption-key.
1.
I do not know why, but seems bad to store a key as a static field in code. May be because it's too easy to read it from here even not running an application.
2.
It seems better to store a key in Keychain and get it from here by request. But to avoid #1 it's necessary to install a key to Keychain while installation process. Is it possible? How to do that?
3.
I do not know what certificates do. Are they helpful to the problem?
4.
To transfer a key from server is also a bad idea, because it's very easy to sniffer it.
The way you solve the sniffing problem is that you communicate over HTTPS for your web service. NSURLConnection will do this easily, and all web service engines I know of handle HTTPS without trouble. This will get rid of many of your problems right away.
On which machine is the 100-1000x decrypt the bottleneck? Is your server so busy that it can't do an asym decryption? You should be doing this so infrequently on the phone that it should be irrelevant. I'm not saying asym is the answer here; only that its performance overhead shouldn't be the issue for securing a single string, decrypted once.
Your service requires SMS such that all users must provide their phone number? Are you trying to automate grabbing the phone number, or do you let the user enter it themselves? Automatically grabbing the phone number through the private APIs (or the non-private but undocumented configuration data) and sending that to a server is likely to run afoul of terms of service. This is a specific use-case Apple wants to protect the user from. You definitely need to be very clear in your UI that you are doing this and get explicit user permission.
Personally I'd authenticate as follows:
Server sends challenge byte
Client sends UUID, date, and hash(UUID+challenge+userPassword+obfuscationKey+date).
Server calculates same, makes sure date is in legal range (30-60s is good) and validates.
At this point I generally have the server generate a long, sparse, random session id which the client may use for the remainder of this "session" (anywhere from the next few minutes to the next year) rather than re-authenticating in every message.
ObfuscationKey is a secret key you hardcode into your program and server to make it harder for third parties to create bogus clients. It is not possible, period, not possible, to securely ensure that only your client can talk to your server. The obfuscationKey helps, however, especially on iPhone where reverse engineering is more difficult. Using UUID also helps because it is much less known to third-parties than phone number.
Note "userPassword" in there. The user should authenticate using something only the user knows. Neither the UUID nor the phone number is such a thing.
The system above, plus HTTPS, should be straightforward to implement (I've done it many times in many languages), have good performance, and be secure to an appropriate level for a broad range of "appropriate."
I don't think you're going to be able to do what you want securely with symmetric encryption. With asym you can send the public key without worrying about it too much (only threat is someone substituting your key with their own) and validate the encrypted unique id on your server with the private key.

How would you keep secret data secret in an iPhone application?

Let's say I need to access a web service from an iPhone app. This web service requires clients to digitally sign HTTP requests in order to prove that the app "knows" a shared secret; a client key. The request signature is stored in a HTTP header and the request is simply sent over HTTP (not HTTPS).
This key must stay secret at all times yet needs to be used by the iPhone app.
So, how would you securely store this key given that you've always been told to never store anything sensitive on the client side?
The average user (99% of users) will happily just use the application. There will be somebody (an enemy?) who wants that secret client key so as to do the service or client key owner harm by way of impersonation. Such a person might jailbreak their phone, get access to the binary, run 'strings' or a hex editor and poke around. Thus, just storing the key in the source code is a terrible idea.
Another idea is storing the key in code not a string literal but in a NSMutableArray that's created from byte literals.
One can use the Keychain but since an iPhone app never has to supply a password to store things in the Keychain, I'm wary that someone with access to the app's sandbox can and will be able to simply look at or trivially decode items therein.
EDIT - so I read this about the Keychain: "In iPhone OS, an application always has access to its own keychain items and does not have access to any other application’s items. The system generates its own password for the keychain, and stores the key on the device in such a way that it is not accessible to any application."
So perhaps this is the best place to store the key.... If so, how do I ship with the key pre-entered into the app's keychain? Is that possible? Else, how could you add the key on first launch without the key being in the source code? Hmm..
EDIT - Filed bug report # 6584858 at http://bugreport.apple.com
Thanks.
The goal is, ultimately, restrict access of the web service to authorized users, right? Very easy if you control the web service (if you don't -- wrap it in a web service which you do control).
1) Create a public/private key pair. The private key goes on the web service server, which is put in a dungeon and guarded by a dragon. The public key goes on the phone. If someone is able to read the public key, this is not a problem.
2) Have each copy of the application generate a unique identifier. How you do this is up to you. For example, you could build it into the executable on download (is this possible for iPhone apps)? You could use the phone's GUID, assuming they have a way of calculating one. You could also redo this per session if you really wanted.
3) Use the public key to encrypt "My unique identifier is $FOO and I approved this message". Submit that with every request to the web service.
4) The web service decrypts each request, bouncing any which don't contain a valid identifier. You can do as much or as little work as you want here: keep a whitelist/blacklist, monitor usage on a per-identifier basis and investigate suspicious behavior, etc.
5) Since the unique identifier now never gets sent over the wire, the only way to compromise it is to have physical access to the phone. If they have physical access to the phone, you lose control of any data anywhere on the phone. Always. Can't be helped. That is why we built the system such that compromising one phone never compromises more than one account.
6) Build business processes to accommodate the need to a) remove access from a user who is abusing it and b) restore access to a user whose phone has been physically compromised (this is going to be very, very infrequent unless the user is the adversary).
The simple answer is that as things stand today it's just not possible to keep secrets on the iPhone. A jailbroken iPhone is just a general-purpose computer that fits in your hand. There's no trusted platform hardware that you can access. The user can spoof anything you can imagine using to uniquely identify a given device. The user can inject code into your process to do things like inspect the keychain. (Search for MobileSubstrate to see what I mean.) Sorry, you're screwed.
One ray of light in this situation is in app purchase receipts. If you sell an item in your app using in app purchase you get a receipt that's crypto signed and can be verified with Apple on demand. Even though you can't keep the receipt secret it can be traced (by Apple, not you) to a specific purchase, which might discourage pirates from sharing them. You can also throttle access to your server on a per-receipt basis to prevent your server resources from being drained by pirates.
UAObfuscatedString could be a solution to your problem. From the docs:
When you write code that has a string constant in it, this string is saved in the binary in clear text. A hacker could potentially discover exploits or change the string to affect your app's behavior. UAObfuscatedString only ever stores single characters in the binary, then combines them at runtime to produce your string. It is highly unlikely that these single letters will be discoverable in the binary as they will be interjected at random places in the compiled code. Thus, they appear to be randomized code to anyone trying to extract strings.
If you can bear to be iPhone OS 3.0-only, you may want to look at push notifications. I can't go into the specifics, but you can deliver a payload to Apple's servers along with the notification itself. When they accept the alert (or if your app is running), then some part of your code is called and the keychain item is stored. At this point, that is the only route to securely storing a secret on an iPhone that I can think of.
I had the same question and spent a lot of time poking around for an answer. The issue is a chicken and egg one: how to pre-poluate the keychain with data needed by your app.
In any case, I found a technique that at least will make it harder for a jailbreaker to uncover the information - they'll at least have to disassemble your code to find out what you did to mask the info:
String Obfuscation (if the link breaks search for "Obfuscate / Encrypt a String (NSString)")
Essentially the string is obfuscated before placed in the app, then you unobfuscate it using code.
Its better than doing nothing.
David
EDIT: I actually used this in an app. I put a base coding string into the info.plist, then did several operations on it in code - rot13, rotate/invert bytes, etc. The final processed string was used to decode the obfuscated string. Now, the three letter agencies could for sure break this - but at a huge cost of many hours decoding the binary.
I was going to say that this is the best technique I've come across, but I just read Kiran's post on UAObfuscatedString (different answer), which is a completely different way to obfuscate. It has the benefit of no strings saved anywhere in the app - each letter is turned into a method call. The selectors will show up as strings, so a hacker can quickly tell that your class used that technique though.
I think that this similar question, and my answer, may be relevant to your case too. In a nutshell, there was some talk of a trusted platform module being present in an iPhone. This would allow your service to trust an iPhone, even in the hands of an attacker. However, it looks like using the keychain is your best bet.
Did you consider/try the Push Notification suggestion, for initially transmitting the secret to the app & keychain? Or end up finding some other method to achieve this?
I'm going have my iphone app upload images to Amazon S3. Instead of putting the AWS credentials in the app, I am going to have the app phone home to my server for the URI and headers to use in the S3 upload request. My server will generate the S3 URI, proper signatures, etc. I can then implement a tighter, more specific security model on my app's webservice than AWS offers by itself and not give away my AWS keys to anyone with a jailbroken iphone.
But there still has to be some trust (credentials or otherwise) given to the app, and that trust can be stolen. All you can ever do is limit the damage done if someone jailbreaks an iphone and steals whatever credentials are in the app. The more powerful those credentials are, the worst things are. Ways to limit the power of credentials include:
avoid global credentials. make them per-user/application
avoid permanent credentials. make them temporary if possible
avoid global permissions. give them only the permissions they need. for instance, write permissions might be broken down into insert, overwrite, delete, write against resource group A or B, etc, and read could be broken into read named resources, read a list of all existing resources, read resource groups A or B, etc.
I would recommend creating a key at run time if possible. This way if the key were to get apprehended during a particular session, once the session ends, the key will be worthless. They could still apprehend the key from memory if they are smart enough, but it wouldn't matter since the key would become invalid after a period of time.
Sounds wonky. Would use HTTPS and maybe an encryption package to handle the key.
I think CommonCrypto is available for iPhone.
EDIT: Still sounds wonky. Why would anyone pass a secret key in an HTTP header? Anyone who traces your network traffic (via a logging wifi router, for instance) would see it.
There are well-established security methods for encrypting message traffic...why not use them rather than invent what is basically a trivially flawed system?
EDIT II: Ah, I see. I would go ahead and use the Keychain...I think it is intended for just these kinds of cases. I missed that you were generating the request using the key. Would still use HTTPS if I could though, since that way you don't risk people deducing your keygeneration scheme via inspection of enough signatures.