Store and retrieve password in database - zend-framework

I am developing an app which uses several API services, the API requires that I provide username and password for API transactions, unfortunately no API token :-( in-order to automate I need to store username passwords somewhere, preferably database, I cannot use hashing because I need to send the username/password to authenticate and process API request, hence I am wondering how to go about it.
If I use Zend\Crypt to encrypt and store the password in database and decrypt whenever required, would this be enough for security? is there something else I must consider?
Looking for pointers.
PS: I am using ZendFramework2 with Doctrine/MySQL for the app.

Usually you would use a token mechanism (like OAuth). If that's not possible, one would use TLS/SSL client authentication.
However, if you rely on plain passwords (on the application-level, I still guess the username/password tupel is transmitted over a secure connection!) and you want to store them encrypted, you have to think of a meaningful mechanism to get an encryption key for your scenario. Just generating an encryption key and storing it on the same machine in plain does not provide more security.
Without more information on your scenario it is hard to make a suitable suggestion.

Related

Which is more better between basic auth and token auth as security perspective

I am currently developing a RESTful API server, and I am choosing between using ID and password or using a token to authenticate a user.
Let me, explain my situation first. I need to include static authentication information to my library to communicate between a client and my server or provide it to a partnership company to communicate between their server and my server. And when I was researching other services which are in a similar situation as us, they are using token now (for example, Bugfender is using a token to specify a user).
However, what I think is that using ID and PW and using the token are the same or using ID and PW is better because there are two factors to compare it is correct or incorrect.
Is there any reason why other services are using a token?
Which one is better as a security perspective or is there a better way to do this?
I think, if you are going go use on your client fixed username/password, or some fixed token, then the level of the security is the same.
Username and password is not considered as multi-factor authentication. Multi factor means that you are authenticating someone by more than one of the factors:
What you know. This can be the combination of username and password, or some special token.
What you have. Might be some hardware that generates an additional one time password - Google authenticator app on your telephone, or SMS with OTP received with some time expiration.
What you are. This is for example your fingerprint or retina of the eye.
Where you are. This can be the IP address of the origin if it is applicable for your setup.
How you behave. What is your normal way of using the service.
etc.
Maybe not needed to mention that both - the token and the username/password combination have to be carried in an encrypted requests (I believe you are using HTTPS). Otherwise the client's identity can be stolen.
How are you going to provide the credentials to your client library? I thnk this is the most tricky part. If those credentials are saved as a configuration (or worse hard coded) on their server, is that storage secure enough? Who is going to have access to it. Can you avoid it?
What would happen if your partner company realize that the username/password is compromised? Can they change it easily themselves? Or how fast you can revoke the permissions of stolen credentials?
My advice is also to keep audit logs on your server, recording the activity of the client requests. Remember also the GDPR if you work with Europe servers, check for similar regulations in your country based on what you are going to audit log.
In case the credentials (ID and password) and the token are being transferred the same way (say: by a header in a REST request) over a TLS secured channel, the only difference lies in the entropy of the password VS entropy of the token. Since it is something for you to decide in both cases, there is no real difference from the security perspective.
NOTE: I don't count the ID as a secret, as it usually is something far easier to guess than a secret should be.
I'd go for a solution that is easier to implement and manage.
IMHO this would be HTTP basic authentication, as you usually get full support from your framework/web server with little danger of making security mistakes in authentication logic. You know, friends don't let friends write their own auth. ;)

Storing passwords on server

I want to do the following
User signs up to IOS app and provides username and password
Make a server call and store password in server database
When user logs in in the future, retrieve that password and check against the password that the user entered.
How can I do this in the most secure way possible? I was thinking of encrypting the password when storing in the db. When the user logsin, use the same encryption algorithm and compare against the db encrypted password.
NEVER ever store user credentials in encrypted (reversible) form. Currently best known way for checking user credentials is slow salted hash
for what and why please read https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/
However, don’t try to invent your own algorithm for repeated hashing.
Choose one of these three well-known ones: PBKDF2, bcrypt or scrypt.
As already commented you may outsource the user authentication to some reliable service (google, fb, aws cognito, ibm appid,...)
Have you tried looking into databases? I know that Firebase has an authentication component of their database for ios development, and you might want to try to look into it or other databases. Check out firebase at: https://firebase.google.com/

Right way to store encrypted info

I need to store a sensible info in a database (clients passwords). Is there a common practice? The information should be accessible by various users. Think about service company that should make maintenance of clients systems.
I'm thinking about using AES encryption. All the information is encrypted with the same main key. For every user this main key is encrypted with the user's password used as the key and stored separately. During login and authentication the main key is decrypted and saved in a session. Later the key is used to decrypt clients info. Is it a good practice?
Thanks
P.S.: Yes, I know that it's better not to use passwords, but it's not me to decide the way to access client's servers.

Is it possible to verify a password hash against another password hash?

Consider the following interaction:
A user stores their username and password on a web server. For the sake of security, the server records a hash of the password plus some unique salt.
While the user is using a client application, it makes a request to the server submitting their username and a hash of the password plus some other unique salt.
So you have the following information on the server and need to know whether or not the request is authentic:
The server's salt
The server's hashed password
The client's salt
The client's hashed password
Again ... client sends: clientSalt + MD5(clientSalt + password). Server has serverSalt + MD5(serverSalt + password). I don't want to know the password, I just want to know if the hashes were calculated from the same password.
Without knowing the password that was hashed, is there any way to verify that both hashes are of the same password?
My goal is to allow some form of secure authentication in a client-server environment without ever exchanging the actual password over the wire. This is just one idea I've had, but I don't even know if it's possible.
That would require unhashing the password, which is not possible. If the server receives: salt, md5sum, it can't see what went into the md5sum.
A challenge-response protocol would work instead. The server should generate a random value nonce and send it to the client. The client calculates md5(md5(password) | nonce)) and returns it to the server. The server verifies by checking md5(storedpassword | nonce).
No, you can't do this.
Once you add a salt into the mix it becomes practically impossible to compare hashes. (To do so would require "un-hashing" those hashes somehow before comparing the "un-hashed" data.)
Challenge-response authentication is probably the way to go, possibly using Kerberos, depending on your tradeoffs. One of the tradeoffs being the possibility for attackers controlling the clients to use compromised hashes to authenticate themselves.
Don't invent your own cryptographic protocols. Use one that is well-known and well tested. If possible, use an existing (vetted) implementation.
My goal is to allow some form of secure authentication in a client-server environment without ever exchanging the actual password over the wire. This is just one idea I've had, but I don't even know if it's possible.
For this, I advise looking into Kerberos: Official Site and Wikipedia
It's impossible. If you don't store password on the server, user must provide it.
OR
If you store password on the server, user can provide hash calculated using requested salt.
You will not be able to verify the hash with this setup.
If you don't want someone to see the password go over the wire, SSL is the easier way.
If you don't want to use SSL, you could check out SRP.
Additionnally: don't use MD5+Salt to store your password, use key strengthening functions like bcrypt or scrypt.

Security of REST authentication schemes

Background:
I'm designing the authentication scheme for a REST web service. This doesn't "really" need to be secure (it's more of a personal project) but I want to make it as secure as possible as an exercise/learning experience. I don't want to use SSL since I don't want the hassle and, mostly, the expense of setting it up.
These SO questions were especially useful to get me started:
RESTful Authentication
Best Practices for securing a REST API / web service
Examples of the best SOAP/REST/RPC web APIs? And why do you like them? And what’s wrong with them?
I'm thinking of using a simplified version of Amazon S3's authentication (I like OAuth but it seems too complicated for my needs). I'm adding a randomly generated nonce, supplied by the server, to the request, to prevent replay attacks.
To get to the question:
Both S3 and OAuth rely on signing the request URL along with a few selected headers. Neither of them sign the request body for POST or PUT requests. Isn't this vulnerable to a man-in-the-middle attack, which keeps the url and headers and replaces the request body with any data the attacker wants?
It seems like I can guard against this by including a hash of the request body in the string that gets signed. Is this secure?
A previous answer only mentioned SSL in the context of data transfer and didn't actually cover authentication.
You're really asking about securely authenticating REST API clients. Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API. SSL without client authc only authenticates the server, which is irrelevant for most REST APIs because you really want to authenticate the client.
If you don't use TLS client authentication, you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth 1.0a or even HTTP Basic authentication (but over SSL only).
These schemes authenticate that the request was sent by someone expected. TLS (SSL) (without client authentication) ensures that the data sent over the wire remains untampered. They are separate - but complementary - concerns.
For those interested, I've expanded on an SO question about HTTP Authentication Schemes and how they work.
REST means working with the standards of the web, and the standard for "secure" transfer on the web is SSL. Anything else is going to be kind of funky and require extra deployment effort for clients, which will have to have encryption libraries available.
Once you commit to SSL, there's really nothing fancy required for authentication in principle. You can again go with web standards and use HTTP Basic auth (username and secret token sent along with each request) as it's much simpler than an elaborate signing protocol, and still effective in the context of a secure connection. You just need to be sure the password never goes over plain text; so if the password is ever received over a plain text connection, you might even disable the password and mail the developer. You should also ensure the credentials aren't logged anywhere upon receipt, just as you wouldn't log a regular password.
HTTP Digest is a safer approach as it prevents the secret token being passed along; instead, it's a hash the server can verify on the other end. Though it may be overkill for less sensitive applications if you've taken the precautions mentioned above. After all, the user's password is already transmitted in plain-text when they log in (unless you're doing some fancy JavaScript encryption in the browser), and likewise their cookies on each request.
Note that with APIs, it's better for the client to be passing tokens - randomly generated strings - instead of the password the developer logs into the website with. So the developer should be able to log into your site and generate new tokens that can be used for API verification.
The main reason to use a token is that it can be replaced if it's compromised, whereas if the password is compromised, the owner could log into the developer's account and do anything they want with it. A further advantage of tokens is you can issue multiple tokens to the same developers. Perhaps because they have multiple apps or because they want tokens with different access levels.
(Updated to cover implications of making the connection SSL-only.)
Or you could use the known solution to this problem and use SSL. Self-signed certs are free and its a personal project right?
If you require the hash of the body as one of the parameters in the URL and that URL is signed via a private key, then a man-in-the-middle attack would only be able to replace the body with content that would generate the same hash. Easy to do with MD5 hash values now at least and when SHA-1 is broken, well, you get the picture.
To secure the body from tampering, you would need to require a signature of the body, which a man-in-the-middle attack would be less likely to be able to break since they wouldn't know the private key that generates the signature.
In fact, the original S3 auth does allow for the content to be signed, albeit with a weak MD5 signature. You can simply enforce their optional practice of including a Content-MD5 header in the HMAC (string to be signed).
http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
Their new v4 authentication scheme is more secure.
http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
Remember that your suggestions makes it difficult for clients to communicate with the server. They need to understand your innovative solution and encrypt the data accordingly, this model is not so good for public API (unless you are amazon\yahoo\google..).
Anyways, if you must encrypt the body content I would suggest you to check out existing standards and solutions like:
XML encryption (W3C standard)
XML Security