I am looking to implment HMAC for my REST API based on
http://www.smartjava.org/content/protect-rest-service-using-hmac-play-20
The one thing I am still confused about is the how to get the SECRET to the client. The clients will be iphone, android and downloaded from the market
What I was thinking of was using something the user has entered as the SECRET like a pin, the server will have this pin via
1) client gets a public key from server
2) encrypts the pin with the public key
3) server stores pin in db
4) from that point forward the PIN in used as the SECRET
Any holes in this?
This would in principle be fine. However, a pin usually is only 4 digits. It would not be difficult for an attacker to get the public key and encrypt all 9999 combinations. He could then compare his encrypted keys with the encrypted data from the client and find the secret. You can avoid this problem by padding the pin with i.e. 50 random characters. The server must decrypt the padded data and simply throw away the last 50 characters.
There is a hole.
At step 3, the PIN is stored in the database. The server has no way of knowing that the request to save the PIN comes from a legitimate user.
For this to work, you must save the PIN either :
At account creation
When the old PIN is provided
That being said, a PIN stays very weak and easy to break. A 4 digit pin will be guessed in about 5000 tries, on average.
I'm not a security expert, but what if the client sent along a random seed with each request? Both the client and server would use this seed in generating a secret key based on a shared algorithm. I'm not sure how attackable the relationship between a given seed and a returned hash would be, however.
Related
I need to send encrypted and dedicated data to a mobile application (ios/android) supposing that the application is not connected to internet.
My current idea is to send the data through a QRCode containing the encrypted data.
I don't want to use symmetric encryption and "share secret" on both sides for obvious security reasons.
I'm a beginner in encryption ;-)
I think that it can be acceptable that the application generates a 16 characters that the user can enter into a web form and then download the QRCode dedicated for this device and encrypted.
Then my feeling is that I'm looking for an asymetric algorithm that can be initiated starting from something like 16 characters.
It's acceptable that the application knows the server public keys, but application won't have possibility to send more that 16char to share their locally generated public key.
Any idea?
Your 16 characters sounds like a one-time password, from which you can derive a symmetric encryption key. Since it's a one-time password (unless the user re-uses this password again and again), there's not much risk in using it. Also you don't store this password (or the derived key) on the server to prevent leakage.
The key can be derived using PBKDF function. Length of user's passphrase is the most important thing - it must be as long as possible (16 characters is quite weak passphrase).
I am trying to implement a security system that has the following requirements:
All clients share a password, which is not known to the server
Each client has a unique client-id, which is known to the server
All clients with knowledge of the password must be able to generate the same shared secret on the server (this secret can be anything, it just needs to be the same for all clients and unique across passwords)
The password needs to remain secure, even if the server or the transport get hacked
It must be impossible for another party with a different client-id to generate the same server-side secret without knowledge of the password
Let me try to give a graphical representation of this:
Client Server
.--------------^-----------. .----------^----------.
f(client-id 1) g(client-id 1)
PASSWORD ----------------> request 1 ----------------> KEY
|| equal || equal
PASSWORD ----------------> request 2 ----------------> KEY
f(client-id 2) g(client-id 2)
Here, f() [g()] are functions that the client [server] applies to the password [request] to obtain the request [key]. These functions may depend on the client-id.
There's two approaches that I have come up with that might do this, but I am hoping for something simpler that requires less traffic and less server load:
"No-brainer": The clients hash the password. The clients and server each use a standard mechanism (like SSL) to secure their connection and send the hash over this connection.
"A little more clever": The server has a fixed private-key coded into it and each client has the public-key coded into it. The clients hash the password, XOR it with their client-id, encrypt the result with RSA/PGP using the public key. The server then decrypts the request using the private key and XORs the result with the client-id to arrive at the password hash.
In both cases, the server ends up with the same secret for the clients: the password hash. The advantage of the second version is that there is no need for the overhead of a full-fledged key exchange and encryption system, since unfortunately I won't be able to rely on SSL in all cases. In fact, it allows me to generate the server secret in a single request without any handshake. The client-id-XOR in the second version are used to prevent replay-attacks, where a third party with a different client-id could otherwise simply send the same encrypted message to the server to generate the same secret. Basically it's a no-overhead way to add a salt.
Now the question:
Since I don't really have any requirements on the server-side secret, not even that the clients can generate this secret locally, is there an even simpler way to do this that doesn't require expensive modular exponentiation of arbitrary-precision numbers like RSA does? I'm thinking of maybe some sort of other trapdoor function for f() and g() above that allows me to achieve the same result.
No takers, I guess... The question is probably too vague...
In any case: For now I've decided to use RSA (i.e. approach 2 from above). It's simple enough to implement and with the right libraries, it's not too expensive to run either.
On the current project I'm working on, we have the following problem.
Our software is a Location Based Services platform and applications can connect and use our services through our exposed webservices using SOAP. Until now our platform was only used by internal applications, but now we would like to open it for third party applications. For that we need an authentication mechanism.
Because of our customers' infrastructure and load balancing solution, we cannot use HTTPS. The original idea was that applications can just use HTTPS and send the password we authenticate.
A solution would be the next:
The application has the password. The application generates a random string (salt) and creates a hash. Then the application creates an HTTP request sending the hash, the salt and a timestamp. This three is enough for us to authenticate, as we can generate the same hash and compare.
My problem is that for this we need to store the password in our database in clear text, because we need to do the same process using the given salt so we can compare the result and authenticate the application. Storing passwords in clear text is unacceptable.
Do you know about any authentication/access control mechanism that would fit this situation? Generally, do you know about any good books/sources about application authentication/access control mechanisms?
Any help is highly appreciated. Thanks in advance!
The application (client) can hash the password two times. Note that the server should generate the other random salt, not the client! Otherwise the attacker can log with this hash also. You can also make it safer by storing password specific salt in the database.
The protocol:
0) servers retrieves salt for that particular password from database, generates salt2, and sends both to the client
1) client sends hash(hash(password, salt), salt2, timestamp) and timestamp.
2) server retrieves hash(password, salt) from the database and compares.
Note that if you are on the network where attackers can not only sniff, but also modify the traffic, as Paulo pointed out, you should sign EVERY message: hash(hash(password, salt), salt2, timestamp, message) and check it at server. (E.g. for the case when the attacker could modify the message to contain delete command...)
Note that there is still a problem when user needs to SET/CHANGE the password safely. You cannot do it safely with just hash function over unsafe network, you need some kind of cipher/decipher.
Also note that the slower the hash function is, the safer (because of the dictionary attack). If you don't have access to special slow hash function, you may also call normal fast hash function 100000 times.
Instead of inventing your own solution, you should use an established one. SOAP has support for cryptographic authentication such as WS-Security - see Craig Forster's comment on this answer for suggestions.
The best choice in other cases is usually oauth; it provides both authorization and authentication, and deals with a lot of cryptographic issues that you're not likely to spot when building your own.
Using an authentication solution which does not contain an integrity check of the whole message (or stream) is insecure.
While the hashing solution originally proposed by Thomas T. (hash(hash(password, salt), salt2, timestamp), where hash(password, salt) is stored in the database, and salt2 is newly generated) makes sure than an attacker can't get the password (or any data which will be useful for logging in after the timestamp expires), it alone does not prevent an active attacker to hijack the session after the authentication, and send any SOAP requests wanted (and intercept the responses).
What would be needed here is some way to make sure that no data is changed. This is known as a message authentication code (MAC). The usual definition of a MAC includes some (shared secret) key and the message as input, and an authentication token as output.
The usual way to use this would be to do some authenticated key exchange at the beginning of the communication (using either a shared secret or some known public key), and then use a part of the now shared secret as the MAC key, which is then used to authenticate following messages.
(Doing this then essentially is a reinvention of SSL/TLS (or parts thereof), potentially doing the same mistakes again.)
If you have only one message to send, you can instead use the MAC as a kind of symmetric signature, using the password hash (salted and generated with a slow hash function) as a MAC key.
Another way to view this would be to take the message to authenticate as an input to the outer hash in Thomas T's authentication scheme. (Make sure to authenticate everything that is worth authenticating.)
On my fingerprint scanner, the fingerprints are stored in the device itself. I'm sure that this is the same as most of them.
How do the scanners protect/encrypt the fingerprint data, so that someone can't extract this information directly from the scanner and use it to authenticate? I know that this would require serious skill, but I'm sure that I'm not the only one who has thought of the possibility.
Fingerprint devices typically do not encrypt or store your fingerprint data. What usually happens is as follows:
the scan of your fingertip is analysed for certain control points
the position of these generates a token
this token is used similarly to a password hash and is passed to the authentication app
communication with the app may be encrypted with a key which is time specific, to avoid replay attacks
Which is similar to how a password hash is stored , as per #Wiso's answer, in a shadow password file, or in a SAM file under Windows.
So if you are looking at controls, the key elements are the algorithm the device uses to generate the token, the comms between the device and the application, and the storage used by the application.
I don't think your device encrypt your fingerprint data. Suppose it does, where will your device store the key to decrypt it? Usually from system password systems create an hash from the password using a salt, look at shadow password.
I was given advice that I am suspicious about so I'm looking for support here to go back and challenge the advice.
I was advised to use Diffie-Hellman to get both sides to agree on a secret key, use the secret key to generate an AES key, and then use AES to encrypt/decrypt passwords that are being transmitted. Pretty much like the sample code here
When using this scheme, the length of the encrypted password is the same as the length of the unencrypted password. Should I be worried about this?
Before, I was using RSA, encrypting the passwords with the receiver's public key. This was resulting in an encrypted length of 256 no matter what the password length. Isn't that better?
You can just pad to whatever length with any data. It doesn't have to be random. As long as it's all encrypted. I think though that is the least of your worries.
Note if you use Diffie-Hellman you still need to authenticate the parameters sent, which you probably need to do with RSA.
The alternatives are:
Use RSA to exchange an encrypted secret key that you then use to encrypt your data.
Use Diffie-Hellman to exchange a secret key and then use RSA to sign values sent to authenticate the transaction.
If you do all this, then you have to also worry about whether exchanges have been replayed to make you reuse keys etc.
To be honest if you need to ask this question then you probably are not qualified to write a crypto protocol. They are extremely hard to get right and not for the faint hearted.
Suggest you use SSL/TLS for your exchange if you need to stream a lot of data. PGP/PKCS#7 if you just need to send a single message.
First off: Don't invent your own authentication protocol. Period. If you do, you WILL get it wrong even if you're using strong encryption. There are a number of existing well documented authentication protocols that have been vetted by cryptographers and thus are thought to be secure. Don't be tempted to "simplify" them, they've already been simplified.
Second: IMHO you should never send passwords on the wire for authentication (I'm not aware of any authentication protocol which does, including the hideously insecure NTLMv1 protocol)[1].
If you're dead set on going down the "roll my own authentication scheme" path, here's how I'd make the scheme you described above more secure (Caveat: I'm not a cryptographer - I believe that there are serious weaknesses in what I'm describing here):
Instead of sending the password directly, send a one-way-function (also known as a OWF, often implemented as a cryptographic hash like SHA256 or stronger) of the password.
In other words, have the server send the client a salt value, add the salt to the password, compute the OWF of the password+salt value and send the OWF result to the server. On the server, add the salt to the password and also perform the OWF calculation. If the results are the same, the password is valid, if they're not it's invalid.
And finally have whatever you do reviewed by a real cryptographer. They will find problems in your implementation and you're going to have to fix them. They're likely to suggest that you abandon your effort in favor of an existing published protocol.
[1] AFAIK, the only time you should send the password on the wire is when you're changing the password and even then, you should pad the length to a multiple of the block size (include the length in the cybertext so that when you decrypt it you can distinguish between the password and the padding).
If you can help it, don't send passwords over the wire at all. Instead, use a scheme like SRP, which authenticates both parties with one password.