C# verify user in Active Directory from Socket conection - c#

I am a .Net developer since its first days. But the last time was quite interesting. I wrote an network basics dll for my own purpose and started to write the fitting iOS client apps. Everything works fine but now I kind of thought about not managing the user data myself, but to use the existing data of the Active Directory. It would not be any kind of problem to send the plain text username and password from the app to the server and do the verification then, but that is not as safe as I want it to be. My personal most preferred way would be:
send username from app to server
get challenged password hash from the AD by the username and the challenge
send the challenge to the client
hash the password with the challenge
send back the hash to the server and check if the hashes are matching
Quite simple straight forward way. I do not have to deal with certificates and can provide a basic security. I know, that in modern times it is not the topmost safe way. But it is sufficient for my needs.
My question is, is there a way to get the hashed password for a user from the ad and do I get the challenge? Or is there an other simple way to provide a easy secure way of verifying an user not in the local network?
Thank you very much in advance
Best regards
Florian

Have you tried using System.DirectoryServices.AccountManagement? It's very simple to verify a login:
bool authenticated;
using (PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, domain))
{
authenticated = domainContext.ValidateCredentials(username, password);
}

As you said this should be a basic authentication but without sending plain password over network. Therefor I would suggest a solution with an asymmetric encryption.
Encrypting the password on client side and send the encrypted message to the server. The server is the only one having the private key and could therefore read the password and validate it with PrincipalContexts ValidateCredentials methods (like itsme86 suggests).
So the steps for your application could be:
ask for public key from app to server
get public key from server
encrypt password with public key
send back the encrypted password together with the user name to the server
server decrypts the credentials and validates them against the AD

Related

Tips for managing security in my applications

I have an ApiRest, the database in MySql and two clients, one is web in angular6 and the other is an Android application.
I want to know what security measures, I must take to keep the information secure in request and response, maybe use pgp or aes or something else and where.
At that moment, I use Https, and for the login, I send the password and the user in plain text in the body of a POST method, to obtain a token, and in the server I do the hashing of this password with a salt, and I save it in the database.
thanks for your help

How should password be transfered for logon in Asp.net Identity

We are using Asp.net Identity (currently version 2). For the purpose of local user authentication, the framework expects clear-text passwords. As far as I understand, this is not the safe method to transfer passwords.
A quick answer can be: use ssl to encrypt password transfer, but this is not a viable solution to everyone.
This is what we think:
The logon form is provided with a one-time random token, then it hashes the password, attaches it to the token and hashes it again. The result is sent to the server.
The server has the hash of the password and the random token, concats them together and if their hash equals what the client sent, proceeds with the logon process.
This is not possible with the current api provided by Asp.net identity: It expects raw password.
What should we do? Rely only on ssl? Is there a way to secure password transfer without ssl?
The web relies on https for securing sensitive information like passwords. I'd say follow the standard. Your hashing algorithm isn't as tried and true as decades of https development.

Client Server Authentication

I am creating a client server communication based on Asynchronous Sockets, my client will send the username and password to the server then the server will replay whether the account is valid, so i want to secure this steps so no one could record the conversation and keep sending it to my client to achieve illegal entry to the secret data
[The Question {Simplified}] How to securely authenticate the client to the server ... ?
[NOTE] I know SSL but i cant afford paying for a certificate so i need a free alternative to provide secure communication between my client and server.
As always, the most secure password is the one, that the server doesn't know, and that is never transmitted. So what you could do is:
On the server, store the username, a random salt ("account salt") and a secure hash of the salted password ("server shared secret").
On login, in a first step let the client transmit only the username (not secret)
The server should reply with the account salt (not secret) and a randomly generated session salt (not secret). It is important, that the server generates the session salt.
On the client, salt the password with the account salt and hash it (keep this as " client shared secret"), then salt the result with the session salt and hash it again. Transmit this as an authentication token (not secret)
On the server, take the salted hash from your DB, salt it with the session salt and hash it - if this matches the authentication token, the connection is authenticated. (Client is authenticated to server)
if you want to additionaly authenticate the server to the client, you repeat the procedure: Client generates a salt, server creates token from it by salting/hashing the stored secret.
If you want to authenticate the single requests (not only the connection), salt them with the shared secret and hash them, send this as a per-request authentication field. Since in a valid login server shared secret and client shared secret are identical,both sides should come to the same result, thus verifying the authentication field.
I typically tell people that if they find themselves doing crypto themselves they are inventing security problems. :) The odds are good you're missing edge cases. I would suggest relying on something that exists already and has been heavily secured.
If you're using managed sockets, there is a version of the stream class that does crypto for you (NegotiateStream). I would suggest starting there and seeing if it can do what you need w/o you having to invent your own.
You could use a combination of public and symmetric keys in order to secure authentication.
First send a public key for the client to send his authentication data encrypted in. If the data is valid, you could then have the client generate his own public key, and have both send symmetric keys to each other via each other's public key.
Something like that should work.
I know that this was posted a few years ago, but I thought that I would add my own two cents here now. Things have changed in the last couple of year. This might help some one else.
I do not want to take anything away from Eugen, excellent work.
The best way to encrypt the traffic between your client and your server is still using SSL/TLS. You can now get free licenses from https://letsencrypt.org/.
It sounds like you already had SSL figured out, so I would plug in with the free certs that you get from the above link
Good luck,
- Andrew

restful WCF service authentication

I have an application which exposes service which is consumed by the web application via Jquery POST and other applications (IPad, Android, etc). I have to create an authentication system which is highly safe but still fast enough.
I thought of making a token which will be passed to the application on login and which will be used for a specific amount of time (say 30 mins) post which it should refresh itself and not expire the session. So I thought of making a token being sent to service and which will generate token. It will accept
UserId
Password (both encrypted with public key)
AppId
The server will decrypt the request by the private key and generate a token which will be valid for a specific time. Now since this would highly depend on the private key (which will be same and thus someone from within system can leak it and misuse it) so i want the private key to be refreshed after a specific time (say 2 hrs).
Question -
How do refresh Private key and ensure that the currently issues tokens will not be rejected.
Is there a better way of doing it
Is there a better way of doing it?
Yes there is, It's called SSL/HTTPS. If you are already using HTTPS then there is no need for any of this crypto-magic. If you are not using HTTPS you are already insecure by design and nothing you come up with will fix that short of re-inventing SSL.
So what should you do if the transport is secure (HTTPS)
Client makes a request for authentication sending username + password in plain-text.
Server verifies the username + password pair against the (hopefully) hashed password stored with the account.
Server responds with a token (encrypted account id, expiration, etc) using a static AES key.
Client uses the token for all authenticated requests.
Easy.
One thing you could do...
To prevent loss of credentials used on non-secure devices you should take a page from Google and others. Rather than having users entering their website passwords, make them visit and log in to your web server. From there they click a 'generate access token for device'. A unique data string (20 or more characters) is generated and recorded with their account. This 'alternate password' can then be revoked by the user from your website.
How can I make this more secure?
You really can't do much better, here is why...
Assume an attacker gains access to your private key. The attacker can then replace your server or play man-in-the-middle while stealing usernames and passwords.
To attempt to prevent this you contrive some PKI exchange to send the password encrypted by a public key the server gave you. I as a man-in-the-middle can simply give you my own public key and access the username and password and then if I choose, forward it to the real server.
--or--
To attempt to prevent this you use some salt + password hash that will be sent to the server in place of the password in clear text. I as a man-in-the-middle can simply give you a fixed value for the salt and then pre-compute a complete rainbow table for that salt value. Now I again have everyone's password (well most) in clear text.
--or--
To attempt to prevent this you use PKI to establish some secret session key and then sign and encrypt every communication. Well, gee... that sounds familiar... see SSL on Wikipedia. Realize that the ONLY thing that makes SSL secure is the protection of it's private keys. Once a private key is lost, all security and trust is lost.
Final notes:
Without being able to protect some encryption key you cannot build a secure communication.
You should also be aware that thousands of man hours have been spent on software implementations of SSL (like OpenSSL) and they constantly find vulnerabilities in their implementations. Your hope of implementing this yourself, and doing it as secure as IIS or OpenSSL, is almost NIL. That is not a Digg on you, that is just reality, I couldn't do it either I only know enough to not even try.
Lastly, my final advice is about your statement: "someone from within system can leak it and misuse it". This is your real problem. Fix that and all else will be much easier. Securing a server environment should be your first priority. Your second priority should be minimizing the impact to your customers once you fail to do the first.
Some helpful links:
How to generate password using a specific set of characters.
Another example of how to store a salted password hash.

Secure login using FormsAuthentication in .net webservice, or is it?

I created a web service that I want to make more secure by using forms authentication. I added the following code:
[WebMethod(Description = "Login function returns true for success and false for fail.", EnableSession = true)]
public bool Login(string Username, string Password)
{
return User.Validate(Username, Password);
}
My User.Validate function does all the authentication and works fine but I am not sure if it is secure passing the username and password to the web service. Is this any less secure than when a username and password field are submitted through a normal web form without SSL?
Is this any less secure than when a username and password field are submitted through a normal web form without SSL?
That's damnation with faint praise. Submitting a password without SSL really isn't secure.
Anyway, it seems like it might be a good idea to start with the basics. Does that article answer what I think is your actual question ("How should I do this correctly?")?
Your web method is no less secure than a normal web form without SSL. Both are basic POST entries (you could make them GETs, but POST is most likely) that send their payload contents (Username, Password) in clear text.
Just a comment: not certain about your strategy of making your web service more secure by adding an authentication method that returns a simple boolean. Most authentication schemes will require the use of a session or authentication token that must be carried around by the client. In a web browser, this is automatic through cookies and such; it requires active management for most clients consuming a web service.
Depends who you need to trust. Client, Transport and/or Server.
Client needs to know the password to enter, so not a real problem.
Transport can (and should) be encrypted using HTTPS - HTTP is not any good.
Server - do you trust the people running the server? Will users use the same passord on the server as in thier company (giving server owner possible password to try to attack you company account)?
A good sanity check for security of the server is if you are offering a change password page or not. Any web-site that allows the user to change the password, will send the password over the line and it will be available in clear text on the server (can be encrypted on the way). This could be avoided, but I have yet to find a site that does it.
Cheers,
Well, passing password is not secure if SSL is not used. Also, if the service is exposing multiple methods then user has to enter the username and password for every method call or the calling application has to persist this information in some place and might lead to other vulnerabilities.
To avoid all these problems and one of the right way to secure a service is to use something similar to the OAuth protocol. This protocol exchanges the username password for request token and then exchanges this request token for access token. Subsequent calls to the webservice will use the access token and not the username password.

Categories

Resources