The ArangoDB docs discuss a couple nonce functions here:
https://docs.arangodb.com/3.1/Manual/Appendix/JavaScriptModules/Crypto.html
I understand the idea that I would create a nonce, send it to the client, hash a password with the nonce and send it to the server. But I don't really understand how these two functions work together to make this all happen.
Can someone elaborate on this documentation and the process? If I hash the nonce and the password together, how do I compare it to the stored password that's already hashed? Just looking for some guidance on the process. Thanks!
Update with more details:
I'm working on auth code. I guess in general I'm trying to understand the two functions in the ArangoDB crypto library and how they work together. The documentation doesn't elaborate very much. I found this workflow on wikipedia:https://en.wikipedia.org/wiki/Cryptographic_nonce But I'm not sure I understand it.
Client login page requests a nonce from server. Server provides. Does the server then store this nonce is the users session for later retrieval?
Client hashes password with nonce from server and a client created nonce as well and sends the username, client nonce, and encrypted password to the server.
How does the server compare the password hashed with the nonce & client nonce, to the already hashed and stored password in the database? Instead of hashing the password with the nonce & cnonce, should it just be encrypted using one of the nonce's as a key?
The ArangoDB crypto library provides two functions createNonce, which is obvious, but then it provides checkAndMarkNonce. How does this fit into the workflow? How can I check the returned nonce unless I store it in a session var? And how can I check the nonce if it's hashed along with the password? Is this wikipedia example just wrong, or am I missing some key components?
Related
I have some questions related to tokens and encryption.
First of all Access Tokens :
Regardless the various attacks(that you need to bear in mind so that you take measures against), would you recommend storing an access token on the client?(localstorage/ cookies).
If yes, will I need to encrypt it and store the encrypted token on the client. However, is that really needed since I am using SSL? You are using SSL to prevent a MIM attack.But since you are using HTTPS, why should we also encrypt the access token?
My second question is related to encryption. For SSL, I understand that I need a certificate (or self-signed certificate to test it locally). However, for encrypting the token, do I need the same SSL's certificate, or can I use an RSACryproProvider to generate a pair of public/private keys?
For Refresh tokens :
I believe the best approach is to save the encrypted refresh tokens in the database. It could be an actual API that reads/Writes refresh tokens in the database. However, the refresh token, must be stored along with some user attribute ie UserId, so you can retrieve it based on i.e userid, email etc. Assuming, I use the UserId, I would encrypt it along with some character and date and store it on the client. Do you agree on that? And also, I am thinking to restrict the access on that API, so that it can only serve requests from a particular server or servers (web farm). What is your opinion about this approach?
I would REALLY appreciate your help, as I am really trying to understand in depth some concepts. If there is something, I don't express correctly, please let me know to rephrase my question.
Thanks
I'm trying to set a cookie so that user can be automatically logged in.
I do not want to query DB for session string when authenticating cookies (basically I need to do that whenever most of my APIs are called, I want to make it faster)
the solution I found is to set a hash in the cookie and try to decrypt it when authenticating, if decryption is successful then log user in.
I am wondering what hashing method should I use? Do I just use a constant salt in my program and hash the userName with that salt, store the hashed userName and original userName in cookie, and try to match userName with decrypted hash upon authentication?
Since I am not familiar with hashing functions, can anyone kindly provide some suggestions on how should I do it in Java?
I recommend you to use an unique token key generated for each session. For example, if a client once logged in from a computer, this token will be valid until the password is changed. Expiring a cookie is not completely secure...
You can also use session variable for a simple authentication. Once you set a session variable for an user, every time this user sends a request with this session id; your session variable will be reached for just this session id. Most of the platforms can also use DB for storing these variables for you.
Two approaches:
1) Create your own authentication framework. In this case I recommend to put in a cookie an encrypted value of a username (I strongly not recommend to use hashing; also please do not put the user password value). For encryption please use AES-256 encryption with BouncyCastle:
256bit AES/CBC/PKCS5Padding with Bouncy Castle
If your framework success to decrypt the cookie – the user is authenticated. If your framework cannot decrypt the cookie or the user is not exist - the user is not authenticated.
2) Please consider to use the Spring Security framework:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html
It is the great framework and solves a lot of authentication / authorization problems.
Your problem is solved by the “RememberMe” feature:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-remember-me
Best regards,
Michael
I don't come from Java background, but your hash key should never be something exposed.
For example:- In your case UserName is key and one of the fellow developers who knows what mechanism you are using can break it down because name is something very common and known.
Don't know what the best way is but I have used UserID(GUID) which is not visible in UI.
I'm currently making some research on the WSSE protocol to secure my api.
I've understood the basis and it is clear in my head.
However I face to a problem.
Let's say I want to generate a ONE-time Digest, I've to concatenate the timestamp, the nonce and the secret password.
However, on the server side, I don't have the clear password stored in database, so I'm unable to check for the digest.
Switching to clear password is not an option.
I can't either provide to the client-side the algorithm used to hash password, because they use salt, and the salt is not available to the client.
The only solution I can think about is to don't hash the Digest, just concatenate the data and base64 them.
That way I'll be able to encode the user password to check for its validity.
As password is transmited in plain text it may not be secure, but what if I force HTTPS to authenticate?
Will it be safe?
As password is transmited in plain text it may not be secure, but what if I force HTTPS to authenticate?
Will it be safe?
Yes, and within normal limits, it is the only way to get it secured.
Just send the full password, but send it over a well secured TLS connection. You can use a secure key derivation function such as brypt or PBKDF2 and input the stored random salt (one per user) and password to retrieve the "hash", which can then be checked to the one stored in the database.
Note that you don't need to send a time stamp from the client. It is of course a good idea to log & limit the number of authentication attempts though. You cannot use a time stamp as input to a hash, the outcome would be different each time the time stamp changes.
I am making a program like yelp. Some people have some accounts. So I got to send the password to the web.
Should I encrypt the password before sending it?
After that what would be the standard password policy others used?
Should the encrypted password be the one stored on the mySQL serve? In other word, there is absolutely no need for decryption?
Basically it's like What encryption procedure I must use to send encrypted 'email' and 'password' values over the HTTP protocoll? but for objective-c
After the user logged in, my program need to tell the server that the user is authenticated already. Does my program need to keep sending password?
There are more than one architecture you can implement, and you have to choose considering many factors, like performance, how many users, server architecture...
Basically, you must use https and not http, store hashed password (MD5, SHA, ecc.) and always check if hashed password is equal to stored hashed password.
You can implement also a "session" using token (you have to create a kind of API server side and then use it on client side) or pass username and password in each call to web service (web service must verify credentials every time is called).
Another "fast" (it's not so fast anyway) solution is to implement (both server-client) a standard protocol like (it's my favorite) oAuth 2. It's used by twitter and Facebook, you can learn more here: http://oauth.net/2/
You might be looking for Base64 encoding:
http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html
When sending passwords via UTF-8 encoded socket transfer, is it considered to be secure if I hash the password using either MD5 or SHA-1 prior to sending out the data? Keep in mind that I plan to compare the hashed password in a SQL database. I am worried that someone could be able to sniff the hashed password in UTF-8 then decrypt the UTF-8 encoding and could obtain my hashed password which could potentially be used to match the password in my database.
If the client just sends the hashed password, then the hashed password is the "password": a sequence of bytes which the client just needs to show to be authenticated. If the attacker can sniff that then your protocol is doomed.
If the authentication protocol consists in just presenting a piece of secret data (call it a password if you wish), then the exchange should occur within a transport medium which ensures confidentiality (so that the secret data cannot be sniffed) and server authentication (so that an attacker may not mimic a server and convince a client to send him the secret data). This is what you get out of a classic SSL/TLS tunnel (a https:// URL, in a Web context).
If you cannot establish a SSL/TLS tunnel with server authentication (i.e. the server has a certificate which the client can verify), then you may want to resort to an authentication protocol with a challenge: the server sends a sequence of random bytes (the challenge) and the client responds with a hash value computed over the concatenation of the password and the challenge. Do not try this at home! It is very difficult to do it right, especially when the attacker can intercept communications (active attacks).
A more generic answer is password-authenticated key exchange protocols. PAKE combines a cryptographic key agreement protocol (such as Diffie-Hellman) and mutual password authentication between client and server, in a way which defeats both passive and active attackers, even with relatively weak passwords (the attacker cannot get enough data to "try" passwords without interacting with either the client or the server for each guess). Unfortunately, few PAKE algorithms have been standardized beyond mathematical description, and the area is a patent minefield.
Well, if someone can sniff hash - he can fake authorization request and send the hash he already know.
Making up secure system is not easy, you would need to do authorization using asymmetric cryptography with properly signed keys to make it secure.
At least add ~100byte random salt, and use SHA1 - this way it would be way harder to bruteforce.
They could brute-force your passwords if they know the hashing algorithm. The simple (and not perfectly secure) solution is to use a challenge/response instead, the server issues a random string ("nonce") to be hashed along with the password hash. This makes your app invulnerable to the kind of replay attacks you're describing.
For more information, see HTTP's digest access authentication
Hm, if you are talking about 'proper' hashing, that means that it will 'encrypt' your password so it won't be decrypt-able, because hashing is one way function, and to decrypt it - it till take some time, and some kind of great CPU power.
If you are concerned at password sniffers, you can take it to the next level - use PRIVATE/PUBLIC key encryption. Server should send a challenge to the client (public key for encryption), client encrypts with it, and only server know how to decrypt it. For same amount of bits, it offers more protection - ie. more muscle is needed to brute force crack it.
Check this out.
How do you check the password on the database side?
If you store the unsalted hash of the password and just compare it to the input, then the hashed password can be sniffed and reused.
It's exactly as if you were storing the password itself in the database in plain text.
If you are afraid of sniffing, use a challenge-response protocol to authenticate, but in this case the secret will be stored in the database (and will be known to anyone who has access to the database).
Alternatively, you can send a password in plain text over a protected channel (SSL), but you will have to install a certificate which will most probably cost you some money (if you are using an authority from a vendor-provided list, i. e. one your customers' browsers won't complain about)