Link to home
Start Free TrialLog in
Avatar of tzak12525
tzak12525

asked on

SSL Question

Hello Experts, I hope you're doing good, here is my question

I want to setup a security application, where I generate a Key, I send it back to the user in question, then, he installs it in his browser let's say 'Firefox' then, when he tries to login to his account, the server looks up at the key installed in firefox through SSL then guarantees the access for the user.
The server or the website should not give the access to the user to login to his account even if he got the correct login and password unless he got that key installed in firefox.

Any idea?

Thank you
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

SSL/TLS does not work that way.  They only encrypt the communications channel and nothing else.  The server and browser negotiate the connection before any data is transferred and it is intentionally invisible to programs running on either end so that it can't be intercepted.  

To use an encryption key in a program or service like you are talking about, you must select a method and generate it yourself.  Keys like that are usually stored as cookies so that they will be sent to the server when a page request is made by the browser.
Avatar of tzak12525
tzak12525

ASKER

Ok Sir, what can you call what i've just described? I'm trying to find a name to what i'm looking for
I don't know that there is a specific name for it though it is a fairly common practice.  I guess you might call it an "security enhanced login method".  MD5 and SHA1 hashes are frequently used for things like this because they are so unlikely to be repeated or decoded.

The biggest problem is securing the method where you set the key in the cookie in the first place.  That first step can't be secured with the same method because the key is not available the first time.
I suspect what you actually want is client-side certificates - normally, those are generated in firefox itself, the signing requests are sent to you and are digitally signed by a CA you supply, then the certificate returned to firefox which can then use it for mutual authentication between client and server.

Done correctly, the certificate can also be used to identify a specific user account server-side, thus acting as a single-signon login in itself, it is usually advisable that the user protect the client side certificate with a password in this case.
I will tell you a little story.

When I was doing help desk job as an internship student, I've been called by a guy who worked in an administration, he wanted me to install him a key in firefox to be able to login to the treasury website and add scholarship for some student, the treasury provided him with a piece of paper where i found the link to download that key, I did, I downloaded it, then i uploaded it in FireFox then, we tried to login into the website, and he was recognized, one day he formatted his laptop, then he couldn't access his account, he called me again and I did the same process.

I'm looking for the same solution where i can generate keys, attribute login/password to the key then guide the user to install/add it into the browser before he can login successfully

What are my options?
What type of server are you using?  What type of application (web, ftp-ssl, ssh, or something else) do you want to use this with.

You can generate a personal /certificate from a server for a specific user and then send that certificate to the user.  They then can import it in Firefox, Windows, other operating systems, or any other system/application that supports client-side certificates aa personal certificate.    These can be at a user level, or a machine level in some instances.  If machine leve, typically there is another level of security that does user-id/password.

As DaveHowe stated this is client-side certificate.

The certificate/key is used as part of the connection setup.  

However, this is done for things like web servers, ftp servers that support ssl, and ssh servers.  

There could be other types of servers/services.
thank you for your reply,

I'll be using CentOS server and the type of application will be WEB or HTTP.

You said :

You can generate a personal /certificate from a server for a specific user and then send that certificate to the user.  They then can import it in Firefox, Windows, other operating systems, or any other system/application that supports client-side certificates aa personal certificate.

This is exactly what i'm talking about and this will be at user level where I will generate a certificate for the user and he will import that certificate into his browser then access the web server that is already using SSL to encrypt Data then login in using his log/pass as provided.

Now, how can i proceed with that?

thank you
SOLUTION
Avatar of giltjr
giltjr
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
While a user self-signed certificate can be used for the site, it has to be the same certificate for all users because the web site itself will only support one SSL/TLS certificate for the connection.  That's the nature of SSL/TLS connections.

If you need a secure id that is different for each user, you can't use SSL/TLS for it.
@Dave Baldwin: server side certificates can be self-signed, but client-side cannot;  if nothing else,  the server will send a list of acceptable CAs for the client cert, which the browser will use to select a suitable cert to present.  Client side certs can also be used to establish a login,  although the exact mechanism varies a bit between backends and servers :)
@Dave Baldwin, what do you think of what @giltjr and @DaveHowe said?


SSL is used to encrypt the traffic between a node and a server... that is clear.

Now, my goal is little bit different,

I want to create a web application where a user has the privilege of 'administrator' only on his account and can create sub-users.

Now, when this admin user logs in, he cans generate a certificate for every sub-user or 'employee' then send it to his email and guide him to import it into the browser before he can access the main web page of the application and specifically that account created for him.

When he does, the server should look at that certificate and look to the root main account where the certificate was requested to be generated then grants the access or denies it.

So this will be like this:

  Main Web application
     Login
       Main administrator account (Company 1)
            sub-account 1
            sub-account 2
            sub-account 3
             etc....
      Main administrator account (Company 2)
            sub-account 1
            sub-account 2
            sub-account 3
             etc....
       


What do you think.
Its doable. If I take Apache as an example - usually, after successful client cert based auth, the DN from the client cert is available in the REMOTE_USER environment variable. that can be then looked up (using mod_php, mod_perl or whatever scripting language you are more comfortable coding in) in a database to give all the permissions and so forth associated with that remote user.


It is cleaner to separate out powers and accounts - have "add a new account" functionality that issues a certificate (that can even be self-service), then "add account as user/administrator" functionality on a per-company basis.  have one "super user" account per company that cannot be removed by normal users, and one overall "root" account that can add companies and company superusers, and you are done :)
Right @DaveHowe, my goal is to enhance the security authentication between each account and the server, do you think my idea is good in terms of security?

You said :

If I take Apache as an example - usually, after successful client cert based auth, the DN from the client cert is available in the REMOTE_USER environment variable. that can be then looked up (using mod_php, mod_perl

Which I'm still confused about, can you give more details? were you talking about a security hole or something?
What you are doing is achievable, however you will either need to download/buy a product that can do this already or build your own.

Apache does not have this function at all, because Apache is not a security admin product, but is just a http server.

What DaveHowe is talking about is using a scripting language, like PHP or Perl)  you can have Apache run a script on the server and after a user logs in the script can lookup information about that user using Apache build in variables.  Then by storing information within a LDAP database the script can also lookup information about that user in the LDAP database.

You can store an attribute stating that userA1 is a group admin for group A and they can create/delete/change users in groupA and that usersB29 is just a "normal" users in group B.

Again, this type of security setup and the programs to do it are NOT part of Apache (or any other web server for that matter).   I think cPanel can do some of this, not sure.
you are right giltjr.

actually my intention was to use OpenSSL combined with SSL through HTTP.

Let me explain one thing: I understand the way you explained roles of users and to which every user belongs and what they can do but imagine this, what if a user got the login/password of a certain employee, they can login and get the data, and this can be anything from sales information or billing or anything.

My goal is : I want to secure the authentication so when even someone got your login/password they cannot login into their account without the certificate imported already in their browser, that certificate tells me that you are the eligible user to login.

You see what i mean?

You said :

you will either need to download/buy a product that can do this already or build your own.

Do you have any names of those products?

and thank you very much for your valuable time :)
its certainly not standard apache - apache has no native way to issue a certificate or private key, however automating openssl into issuing this isn't difficult.  I am also not aware of any system out there that uses such a solution (where client side certificates are used, they are usually either issued from the MS CA (in all cases I have seen other than the SAP R/3 community site) or created out-of-band and emailed as pkcs #12 files.  You could certainly "steal" code from the OpenCA project to do this, if you were coding it yourself.

As I am comfortable coding my own sites, I tend to think in terms of "how would I do this" not "what product can I buy that will do this already" :)
Ohh, no i was looking for a product that has been already made just to see its functionality that's all, my project is pure and will be built from the scratch, I just have a question, do you think there is a mechanism to store those keys in LDAP so when the user logs in, the script will check the key against the user information in LDAP... what do you think?
For client-side SSL certificates to be truly secure, the certificate must be generated by the client themselves such that they alone hold and protect the secret key and the server administrator only has the public cert.

The problem with this is that it is almost always ONLY the server administrator that cares enough about security to bother to learn how to do it.  

When the server administrator generates and provides the user's SSL certificates that is no more secure than the server administrator choosing the passwords.
If you want to use standard client-side TSL/SSL with Apache, you can't store the certificate in LDAP database.

I think cPanel can do some of this, not sure about all of it.  I've never had to do client side certs.  The only time I have to allow "group admins" the operating system and it security product supported group admins already.  And before you ask, that OS, the hardware it runs on, and the security product is way to expensive for you.
You don't need to check the key against ldap (although that's an option)

the clientside certificate needs to be signed by a CA under your control, and contain the user's unique username as its identifier; once that is done, each time the user connects, your scripts will have that username available to determine what they are or aren't allowed to do - ldap is an option for that too, but a plain db is easier.

@AlexPace: yeah; so until Internet Explorer supports SPKAC properly, that is going to mean doing something fancy with a java library I guess....
I don't see how the standard SSL/TLS process will support unique ids for each client.  While I'm sure that you can all kinds of specialized processes, I don't know what they are.  What is required on the server and the client to support that?
@Dave Baldwin.  Nothing is required to support it.  Client side certs work just like server side certs.  Each client has its own certificate signed by a CA, so each client has its own private key.  As long as the server trusts the CA it will accept the clients cert.  

In fact a client can have more than one cert and that is where the slight difference is when the server asks the client for its certs, the server sends a list of CA's it trusts.  The client must then choose a cert that is signed by one of those CA's.

So I can run my own CA and you can run your own CA.  "User#1" will need to get a cert signed by me and a cert signed by you.  When they access my site I send a client cert request with only my CA in the list and the client is supposed to respond with the cert signed by me.  When they access your site, you send the client cert request with only your CA in the list and the client will respond with the cert signed by you.
@Dave Baldwin: the unique id is the data held in the client side cert - the whole cert is sent on request from the server, and validated by digital signature (from the client) and the CA's signature (from the cert) - once accepted, that data is exposed to the serverside scripting, and can be used as an id (similarly to how you would use a cookie for session persistence)
once accepted, that data is exposed to the serverside scripting
Ok, how does that happen?  I ask because I don't know and never heard of it.  The question is about having a cert that identifies the client.
@DaveBaldwin:
  In apache, its dumped into environment variables, most particularly REMOTE_USER if you include the directive FakeBasicAuth - not the most readable of things, as its dumped semi-raw, but you can fairly easily extract what you want from it.  I believe IIS has copied the mechanism for compatibility reasons, but I haven't ever had to use it in IIS :)

A list of the environment variables can be found here:

http://httpd.apache.org/docs/2.2/mod/mod_ssl.html

look in particular at the variables beginning SSL_CLIENT_ - those expose various items from the client certificate, more than you could ever want :)

Of course, you then need to impose more structure on it - while its possible to embed the authorizations in the cert too, its more flexible to store that separately in a db table.
Now we're getting somewhere.  I see that those items are not provided in the default configuration and would not be provided on shared hosting.  But then for the kind of security that @tzak12525 is wanting, you can't do it on shared hosting anyway.

So if the cert does not validate because it is self-signed, then access is denied.  If it does validate and the HTTPS connection is made, then the server code can check and see if the info in the SSL_CLIENT_ fields matches the username and password provided in the login.  Is that correct?
@DaveBaldwin:

mod_ssl isn't part of the default configuration? I don't want to get hosting where you do :)

More seriously though, most of the directives can be dropped into a .htaccess, even on shared hosting, but if you are going to the extent of using clientside certificates, you probably want better serverside security than that as your statement says. I have no idea how non-apache shared hosting would work - as I have only ever done this in the past on Apache (I must try it on lighttpd and nginx at some point :)

Cert would not even be *sent* if self-signed - the server sends a list of acceptable CAs (set with the SSLCACertificateFile directive) for client certs, and the browser then picks a suitable cert signed by one of the CAs (if there is more than one choice, it prompts the user usually) - for most implementations, you create a specific issuing CA for the client certs, not trusting a commercial CA for that task (besides, its cheaper, and there is a risk of confusion if a client might have more than one certificate from a single CA to respond back to the server with)

If the certificate is deemed within its validity period and correctly signed by the nominated CA or CAs, the information in it is dumped into the environment variables so that the serverside code can use it and the session proceeds - if not, the session fails before the serverside code is even executed.

Normally, there *isn't* a username and password provided, the certificate, in itself, is considered enough, and the information on which user has presented a certificate is taken from the environment variables and used to look up their account details.
SSL is enabled but the SSL environment variables are not on any hosting that I have seen.  It says in the page you linked that the environment variables are not enabled by default.  I have several programs / pages in several languages (PHP, Perl, ASP, ASP.NET) that I use to dump the server variables and I have never seen any of the SSL_CLIENT_ variables listed.
@DaveBaldwin:
  Yup, you need the StdEnvVars directive which you can put in the .htaccess file, it doesn't need to be in the main config (hence, can work fine even on shared hosting where you have no access to the main config) - but yeah, I was going for comic effect, obviously it fell flat :)

You can do a LOT in .htaccess - I have done rewrites in there, for example. oddly, what I very rarely do is actually define access in htaccess :)
Tried it, seems to work fine.  Cool.
@DaveBaldwin: Well, once in a while, you can go on EE and learn. It must make a refreshing change from being the one explaining all the time :)
But that's what I'm here for.  Answering questions is just a way of learning.  I've seen a lot of things here that I've never heard of before.  Like this question.
I am clearly unlucky then - I keep getting asked things I have done before :)

Admittedly, not with nginx, lighttpd, or IIS - which I would have had to research :)
I keep thinking I should install nginx and lighttpd... but it never gets high enough on the list to get done.  One of my 'searches' is All Questions.  Some days I look at every question that is posted in every topic just to see what is going on.  And there are a lot of questions that people put in the wrong Topic Areas and I suggest to them that they "Request Attention" and get that changed.
You pretty much describe my day job - I get enough "learning opportunities" at work that I don't look for extras on EE :)
@DaveHowe and @Dave Baldwin: I was told once the best way to become an expert in something it to try and teach it to somebody else.   Looking at both your profiles, you two are doing a great job and contribute a lot here on EE.

Now back to the question, tzak12525 you seem to be asking for 3 things now:

1) Using client side certificates to help validate users in addition to using user-id/passwords.

2) Setting up "groups" with a "group admin" that can administer users within those groups.

3) Using both #1 and #2.

I know #1 and #2 can be done, not sure about #3.

For #1)   There are many articles on how to setup Apache to accept client side certs and how to setup your own CA to sign certs.  Now in reality the certs are not as much for the user as they are for the device the user is on.  Since the key is stored on the device.  If the user uses 5 different devices, they must install the signed cert on every device. Since the cert is on the device, as long as somebody has access to the private key, they can get in through the 1st level of security.  You will want them to use a user-id and password on top of the cert.

For #2) I know it can be done.  I am a customer of a few hosted services, that use shared hosting (web and e-mail).  On those services I am an admin for "my site".  As an admin I can create user-id and set permissions for those users.  The hosted services that I work I believe they have written there own custom software to do this, so I'm not sure if there are any products that can do this.  If there are, you would need to run your own server, now it could be a virtual server, say like Amazon E2C , but I doubt if you could do this on a shared web server service.  You would need to control parts of the OS in order to become a CA.  I doubt if you can do that if all you have is access to some of the web server service.

For #3) Combining #1 and #2.  That I am not sure of, because I don't know how easy it would be to setup a CA that would be unique to each group.  Which I would think you may want to do.  Not sure.
Well, the theory (called Gadwell's rule) is that you need 10,000 hours of practice to go from an amateur/novice to an expert.  Obviously, quite a bit of rule-of-thumb there, but it seems relatively accurate - and EE could be considered practice :)
Thank you very much everyone, and specially @giltjr for your ideas, I really agree about what you described in your comment ID: 39742182 you can say that i want levels in security, first, the authentication of the user through the certificate then the use of the username and password, there might be other ways like asking questions randomly time to time to check the authentication of the real user.

Now, for me there are 2 challenges:

- 1st: how can I let admins generate the certificate through the web interface for their users.
I mean, how to make an automated system that will let those Certificate to be generated without doing them manually by me or the owner of the website.

-2nd: Is there a way that I can do to assign a certificate for a particular user and while signing-In the system will check the imported certificate in the client's machine or computer against the certificates lists in the server.

Here is an example to be more clear:

I'm the admin of an account that belongs to "Company X" I have several users each one works in a different department, Now, to let this user access his account, I generated him a certificate and i exported it then sent it to him, he installed it.

When he tries to login, I want that the main system or the server to check for that particular certificate and see if it matches for that user under that company X. Does it make any sense to you?

I've seen that you were talking about LDAP and plain database, but can you give me more information please?

Thank you
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial