OpenSSL: is it possible to attach extra string for authentication? - authentication

For certificate authentication, when a certificate is being sent to the remote side is it possible to attach an extra string, such that the certificate will be displayed along with the special string?
The idea proposed for my project is: A creates a random string, A sends the random string along with its certificate to B, A sends the random string via different media to B, finally B sees the certificate and also compares the string to authenticate A.
Anyway, the fundamental problem is: A and B do not share common in their certificate verification path, and they still want mutual authentication.
Although the proposed one is implementable, I don't know how to reduce the amount of work by leveraging available OpenSSL API's more efficiently. If I end up doing encryption and socket level send/recv by myself, that will be nightmare. Or is there any other tools can achieve that? Thanks a lot.

If the certificates can not be validated and trusted for whatever reason, it makes sense not to use them at all then. TLS supports alternative authentication schemes including OpenPGP, pre-shared keys and one-time passwords. OpenSSL supports pre-shared keys, if memory serves, and there exist alternative libraries depending on the platform.

Related

Can I implement TLS by skipping some steps?

Is it possible to have a cut down implementation of TLS , where we just
presume the server we are connecting to is trusted - after the server sends its
certificate, can we bypass verification of this and do away with any further
processing , and get right into standard http ? Is using public key encryption
something that is absolutely necessary , or can it be skipped ?
Rewording my question.
Is it possible to write a tls engine by skipping the need to use RSA public key
code ?,
or
Can a client notify the server during the handshake that it just requires the severs certificate
info, company name, expiry dates and requests the secret cipher key to be sent in plain text.
Skipping something in a protocol I don't fully understand is generally a bad idea.
Only steps marked as optional in the RFC can be safely skipped.
Therefore if you don't plan to use client-side certificate based authentication you can skip it.
However what you can do however is limit the number of variations in your implementation. This means support only one TLS version (e.g. TLS 1.2) and support only one dedicated cipher suite.
Anyway the pitfalls when implementing TLS are so numerous that I recommend you to use an existing implementation (e.g. implementing in a way that does not allow side channel attacks is not that simple and requires knowledge on that topic). There are other implementations beside OpenSSL with a much smaller footprint.
BTW: If you can presume the connection is trusted you don't need TLS. If you need TLS it should be a secure.
where we just presume the server we are connecting to is trusted - after the server sends its certificate, can we bypass verification of this and do away with any further processing
The point of verification is less to find out if the server is trusted, but more that you are actually talking to the server you expect to. If you omit this step you are open to man-in-the-middle attacks.
But, TLS is a very flexible protocol and there are actually ways to use anonymous authentication or a shared secret with TLS and thus skip usage of certificates. Of course in this case you would need to have some other way to validate the server, because otherwise you would be still open to man-in-the-middle-attacks. And because this use case is mostly not relevant for the common usage on the internet it is usually not implemented inside the browsers.

apache client authentication - set fingerprint of client certificate as header value

i have a working ssl client authentication setup. is there a way to get the client certs fingerprint and put it in the request header when forwarding the request to another app?
according to:
http://httpd.apache.org/docs/current/mod/mod_ssl.html
there is nothing like:
RequestHeader set SSL_CLIENT_X_FINGERPRINT "%{SSL_CLIENT_X_FINGERPRINT}s"
any help appreciated
marcel
The closest thing you can do is to pass the whole certificate (SSL_CLIENT_CERT) and compute the fingerprint once it gets to your application.
Depending on how it's implemented, this shouldn't be too hard to do. For example, you could implement a Filter to do it in a Java servlet environment if needed: decode the PEM-encoded certificate to get it in DER form, pass the byte[] array you get to a MessageDigest initialised with the algorithm you require (and possibly hex-encode the result).
Note that "fingerprint" is a rather loose word. Most tools would use SHA-1 nowadays, but this hasn't necessarily always been the case (and this could change).
As a side-note, what you're trying to do suggests you're not using traditional PKI for authentication, but accepting potential self-signed certificates (or certificates signed by unknown CAs) and compare those fingerprints against a list you know. If this is the case, you're probably not interested so much in the "X.509 certificate" aspect of all this, but you're only using this certificate as a public key container (for which SSL/TLS would guarantee you the client has the matching private key), therefore you might find it more flexible to compare public keys, rather than certificates.

Add RSA based encryption to WCF service without certificates

I am looking for a way to encrypt messages between client and server using the WCF. WCF offers a lot of built in security mechanisms to enrcypt traffic between client and server, but there seems to be nothing fitting my requirements.
I don't want to use certificates since they are too complicated, so don't suggest me to to use certificates please. I don't need confidentiality, so I though I'll go best using plain RSA.
I want real security, no hardcoded key or something. I was thinking about having a public/private keypair generated every time the server starts. Both keys will only be stored in RAM.
Then wen a client connects it should do exactly like SSL. Just as described here.
1.exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
2.using that private/public key pair, exchange a common shared secret, e.g. an "encryption key" that will symmetrically encrypt your messages (and since it's symmetrical, the server can use the same key to decrypt the messages)
3.setup infrastructure on your client (e.g. a WCF extension called a behavior) to inspect the message before it goes out and encrypt it with your shared secret
That would be secure, wouldn't it?
Is there any existing solution to archive what I described? If not I'll create it on my own. Where do I start best? Which kind of WCF custom behaviour is the best to implement?
EDIT:
As this is NOT secure, I'll take the following approach:
When Installing the server component a new X509 certificate will be generated and automatially added to the cert store (of the server). The public part of this generated certificate will be dynamically included into the client setup. When running the client setup on the client machine the certificate will be installed into the trustet windows certificate store of the client.
So there's no extra work when installing the product and everything should be secure, just as we want it.
You've said you don't want to use certificates. I won't push certificate use on you, but one thing you are missing is that certificates serve a purpose.
A certificate proves that key you are negotiating an SSL connection with belongs to the entity you think it belongs to. If you have some way of ensuring this is the case without using certificates, by all means, use raw keys.
The problem is, in step 1:
1.exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
How does the client know that the public key it received from the server wasn't intercepted by a man-in-the-middle and replaced with the MITM's key?
This is why certificates exist. If you don't want to use them, you have to come up with another way of solving this problem.
Do you have a small, well-known set of clients? Is it possible to preconfigure the server's public key on the client?
Alexandru Lungu has created an article on codeproject:
WCF Client Server Application with Custom Authentication, Authorization, Encryption and Compression
No, it would not be secure!
since there's no confidentiality, an attacker could do a men in the middle attack, and all the security is gone.
The only real secure way of encrypting messages between server and client IS to actually use digital certificates.
I'm sorry, the only two methods of providing secure communications are:
Use a public key infrastructure that includes a chain of trust relationships, a.k.a. certificates
or
Use a shared secret, a.k.a. a hardcoded key.
Nothing else addresses all of the known common attack vectors such as man-in-the-middle, replay attack, etc. That's the hard truth.
On the other hand I can offer you an alternative that may alleviate your problem somewhat: Use both.
Write a very, very simple web service whose only job is to generate symmetric keys. Publish this service via SSL. Require end user credential authentication in order to obtain a symmetric key.
Write the rest of your services without SSL but using the symmetric keys published via the first service.
That way your main app doesn't have to deal with the certificates.

How secure this signature based authentication for mobile devices is

I am implementing an app where I don't have a system requiring username and password. What I do require is a name and a phone number.
The scenario is like this:
1) user opens the app for the first time
2)app makes a request to my server and gets a unique UserKey
3)from now one any request the app makes to my REST service also has a signature. The signature is actually a SHA(UserKey:the data provided in the request Base64Encoded)
4)The server also performs the same hash to check the signature
Why I don't use SSH:
not willing to pay for the certificate
I don't need to send sensitive data like passwords, so I don't see the benefit of using it
I just need a simple way to call my own WCF REST services from own app
I understand that there is a flow of security at step2 when the UserKey comes in cleartext, but this happens only once when the app is first opened. How dangerous do you think this is?
What would you recommend? Is there any .NET library that could help me?
Actually, there are several problems with that approach. Suppose there's man-in-the-middle whenever you make a request to the server. By analyzing, for example, 100 sent packets he would recognize similar pattern with signature in your requests. Then he would forge his own request and add your signature. The server checks the hash - everything's alright, it's you and your unique user key. But it's not.
There's a notion of asymmetric keys in cryptography which currently is really popular and provides tough security service. Main concept is the following: server generates two keys - public and private; public key is used to encode texts; they can be decoded only with the use of private key, which is kept by the server in secure location. So server gives client the public key to encode his messages. It may be made double: client generates public key and gives it to the server. Then server generates keys and gives encoded with client's public key his own public key. This way it's almost impossible for man-in-the-middle to make an attack.
Better yet, since the problem is really common, you could use OAuth to authorize users on your website. It is secure, widely used (facebook, g+, twitter, you name them) and has implementations already in variety of languages.
Since you control both the application itself and the webservices, you can do this with SSL (which gets rid of the problems with your current approach) without paying for anything. You can create a self-signed certificate and install that on your webserver; configure the SSL context of your client application to only trust that one certificate. Then, create a client-side self-signed certificate and install that within your application. Set the server up to require mutually-authenticated SSL and only allow your self-signed certificate for access.
Done. You client will only talk to your legitimate server (so no one can spoof your server and trick the client in to talking to it) and your server will only talk to your legitimate clients (so no one can steal information, ID, etc). And it's all protected with the strong cryptography used within SSL.

Client-side SSL theoretical question

I work at company X and we want to engage in a B2B transaction with company Y. In doing so, Y is requiring client side authentication; they already provide server-side authentication - so this would be a mutual SSL transaction.
My understanding is that I simply need to provide my CA-signed cert as part of my client side HTTPS communication. In doing so, asymmetric cryptographic guarantees (i.e., public/private key technology) ensures that I am who I claim I am - in effect, it is not possible to impersonate me. (the root CA has ensured I am who I am, that is why they signed my cert, and it's possible to prove that I didn't "manufacture" the certificate).
Here's my question: is this all I need to provide company Y?
Alternatively, do I have to provide them with another key in advance, so that they can ensure I am not a rogue who happens to have "gotten a hold" of a root-signed certificate for me (company X)? It would seem that if one has to provide this extra key to all parties he wishes to engage with on the client side, it would seem to make client-side SSL not as scalable as server-side SSL. My guess is that it's not possible for one to "get a hold" of a client side cert; that the actual transmission of the client side cert is further encoded by some state of the transaction (which is not reverse-engineerable, feasibly).
Does this make sense and am I right or am I wrong? If I'm wrong, does Y in effect need to get an "extra" pre-communication key from every party that connects to it? (which they want to verify)?
Thanks.
===
Thanks for the responses below, at least the first two have been helpful so far (others may arrive later).
Let me talk in a bit more detail about my technical concern.
Suppose company Y attempts to "re-use" my client side cert to impersonate me in another client-side transaction with another company (say "Z"). Is this even possible? I am thinking - again, perhaps poorly stated - that some part of the transmission of the client side certificate prevents the entire key from being compromised, i.e., that is not technically feasible to "re-use" a client certificate received because you could not (feasibly) reverse engineer the communication which communicate the client cert.
If this is not the case, couldn't Y re-use the cert, impersonating X when communicating (client-side) to Z?
ps: I realize that security is never 100%, just trying to understand what is technically feasible here and what is not.
Thanks very much!
===
Further technical details, I appreciate any additional input very much - this has been very quite helpful.
From a layman's point of view, my concern is that when a client sends his client cert, what is he sending? Well, he has to encrypt that cert using his private key. He sends the ciphertext with the public key, and then a receiving party can use that public key to decrypt the private-key-encoded payload, right? That makes sense, but then I wonder -- what prevents someone from hearing that communication and simply re-using the private key encoded payload in a replay attack. Just replay the exact ones and zeroes sent.
Here's what I believe prevents that -- it can be found in the TLS RFC, in multiple places, but for example in F.1.1:
F.1.1. Authentication and key exchange
TLS supports three authentication modes: authentication of both
parties, server authentication with an unauthenticated client, and
total anonymity. Whenever the server is authenticated, the channel is
secure against man-in-the-middle attacks, but completely anonymous
sessions are inherently vulnerable to such attacks. Anonymous
servers cannot authenticate clients. If the server is authenticated,
its certificate message must provide a valid certificate chain
leading to an acceptable certificate authority. Similarly,
authenticated clients must supply an acceptable certificate to the
server. Each party is responsible for verifying that the other's
certificate is valid and has not expired or been revoked.
The general goal of the key exchange process is to create a
pre_master_secret known to the communicating parties and not to
attackers. The pre_master_secret will be used to generate the
master_secret (see Section 8.1). The master_secret is required to
generate the certificate verify and finished messages, encryption
keys, and MAC secrets (see Sections 7.4.8, 7.4.9 and 6.3). By sending
a correct finished message, parties thus prove that they know the
correct pre_master_secret.
I believe it's the randomization associated with the session that prevents these replay attacks.
Sound right or am I confusing things further?
As long as you keep the private key safe (and the CA keeps their signing key safe), "company Y" doesn't need any other information to authenticate you. In other words, they can be sure that a request really came from the subject named in the certificate.
However, this doesn't mean that you are authorized to do anything. In practice, most systems that use client certificates have an "out of band" process where you provide the "subject" distinguished name that is specified in the client certificate, and the system assigns some privileges to that name.
In fact, because of some practical limitations, some systems actually associate the privileges with the certificate itself (using the issuer's name and the certificate serial number). This means that if you get a new certificate, you might have to re-enroll it, even if it has the same subject name.
A certificate only assures a relying party you have a certain name. That party needs some additional mechanism to determine what you are allowed to do.
Unlike authentication mechanisms based on "secret" (symmetric) keys—e.g., passwords—a server only needs public information for asymmetric authentication. A private signing key should never be disclosed; it's certainly not necessary for client authentication.
With symmetric, password-based authentication, the client and server get access to the same string of bytes—the secret key. With public-key cryptography, only the public key of a key pair is disclosed. The corresponding private key is never disclosed, and no practical method for figuring out the private key from the public key has been discovered.
As long as you keep your private key safe, the server at company Y cannot forge requests that appear to come from you.
Client authentication replay attacks are defeated by requiring the client to digitally sign a message that includes a number randomly generated by the server for each handshake (this is the "random" member of the "ServerHello" message). If the packet used to authenticate the client in a previous session were re-used, a server will be unable to verify the signature, and won't authenticate the replay attack.
RFC 2246, Appendix F.1.1.2 might be a more helpful reference—especially the third paragraph:
When RSA is used for key exchange, clients are authenticated using
the certificate verify message (see Section 7.4.8). The client signs
a value derived from the master_secret and all preceding handshake
messages. These handshake messages include the server certificate,
which binds the signature to the server, and ServerHello.random,
which binds the signature to the current handshake process.
Your client-side certificate (or more precisely its private key), is only as secure as your company's online and/or physical security let it be.
For extremely secure relations (which typically do not have the requirement of scaling much), it may be acceptable that the provider of the service requires an extra element in the protocol which allows them to identify your site (and more often than not, to identify a particular computer or individual within the company, which is something client certs do not fully do.)
This of course brings the question: what is warranty that this extra bit of authentication device will be more securely held by your company? (as compared to the client-site certificate itself). The standard response for this is that these extra bits of security elements are typically non-standards, possibly associated with physical devices, machine IDs and such, and are therefore less easily transportable (and the know-how about these is less common: hackers know what RSA files to look for, and what they look like, what do they know of the genesis and usage of the KBD-4.hex file ?)
Extra question: Can Y make use of my client-side certificate elsewhere?
No they [normally] cannot! The integrity of this certificate lies in your safe keeping of its private key (and, yes, a similar safekeeping from the certificate providers...). Therefore, unless they are responsible for installing the said certificate, or unless their software on your client (if any) somehow "hacks" into certificate-related storage / files / system dlls, they should not be able to reuse the certificate. That is they cannot reuse the certificate any more easily (which is theoretically NP hard) than anyone that, say, would sniff the packets related to authentication as the client establishes a session with the Y site.
Extra questionS ;-)
- What is the nature of the client cert?
- Man-in-the-middle concerns...
Before getting to these, let's clear a few things up...
The question seems to imply TLS (Transport Layer Security) which is indeed a good protocol for this purpose, but for sake of understanding, the keys (public and private) from the certs (server's and client's) could well be used with alternative protocols. And also, TLS itself offers several different possible encryption algorithms for its support (one of the initial phases of a TLS session is for both parties to negotiate the set of algorithms they'll effectively use).
Also, what goes without saying... (also goes if you say it): the respective private keys are NEVER transmitted in any fashion, encoded or not. The confusion sometimes arise because after the authentication phase, the parties exchange a key (typically for a symmetric cipher) that is used in subsequent exchanges. This key is typically randomly generated, and of totally different nature than the RSA keys whether public or private!
In a simplified fashion, the client's certificate contains the following information:
- The Certificate Authority (CA aka issuer)
- The "owner" of the certificate (aka Subject)
- Validity date range
- the PUBLIC key of the certificate
In more detail, the certificates are typically found in an X.509 wrapper (? envelope), which contains additional fields such as version number, algorithm used, certificate ID, a certificate signature (very important to ensure that the certificate received wasn't tempered with). The X.509 also provide for optional attributes, and is also used for transmitting other types of certificate-related data (such as the CRL)
Therefore the certificate's content allow the recipient to:
- ensure the certificate itself was not tempered with
- ensure that the issuer of the certificate is one accepted by the recipient
- ensure that the certificate is valid/current and not revoked
- know the public key and its underlying size and algorithm
With regards to man-in-the-middle concerns, in particular the possibility of "re-playing" a possibly recorded packet exchange from a previous session.
The protocol uses variable, possibly random MACs (Message Authentication Codes) for that purpose. Essentially, during the negotiation phase, one of the parties (not sure which, may vary...) produces a random string of sorts and sends it to the other party. This random value is then used, as-is (or, typically, with some extra processing by an algorithm known by both parties) as part of the messages sent. It being encoded with the private key of teh sending party, if the the receiving party can decode it (with sender's public key) and recognize the (again variable) MAC, then it is proof that the sender is in possession of the private key of the certificate, and hence its identity is asserted. Because the MACs vary each time, pre-recorded sessions are of no help (for this simple purpose).