I am confuse regarding aspects of password encryption the following scenario. While debugging a network response from a Android app using fiddler or wireshark which create a type of proxy server that allows me to see whatever request going from the app to the server. In the response in raw format is the password and it is clearly visible in the post request. As on server end by using password_hash and password_verify we are protecting password. But if someone else on network end can view password then encryption at server end is no use.
Is their any way I can send encrypt password from app and it's converted in some other form and after that password _hash function encrypt it. (even in HTTPS I can see post request)
The solution to securing the password in transit with HTTPS is to "pin" the certificate. Essentially that means to verify that the certificate received on establishment of the connection is to the correct server.
MITM and proxy attacks use a certificate that is not a valid certificate for the server and will be refused.
See: HTTP Public Key Pinning.
Related
I am trying to build a client / server servlet application with these general requisites:
both the client and the server are jetty embedded;
the server expose a servlet in order to receive json data via POST;
the connection must be secured via SSL (i.e. the connection will be done via Internet via https);
I want that only my Jetty client be able to send data to my server, all other tentative must be refused by the server;
the server and the client are unattended machines (i.e. not password via command line could be inserted by human);
no password in clear must be stored on the client device. In general I don't want someone could open the remote client device and stole the password and building a fake remote device capable to send data to my server too.
I have build a perfectly working client / server application via HTTP but I am confused about the security.
I have read that there is the possibility to use client / server mutual authentication and seems what I am looking for but I can't get the complete picture.
In this document client-certificate-authentication there is a more or less clear explanation about how to build a shared trusted CA but the password for accessing the TrustStore and the KeyStore are in clear in the code.
I think I am missing a tile in the puzzle.
Could someone point me in the right direction?
Thanks,
S.
I'm going with a simple answer (for now).
If you just want only your clients to talk to the server, then yes, Client SSL/TLS certificates are the way to go.
You'll want the server's SslContextFactory.Server.setNeedClientAuth(true) set to true. That will in turn cause Java's javax.net.ssl.SSLParameters.setNeedClientAuth(true) to be set on incoming connection establishment. If the client fails to provide the client certificate, the connection is closed, and no HTTP request is sent or processed.
As for securing the client certificate, that's up to you, you can do anything you want to do, as long as it results in a valid client SslContextFactory.Client that the Jetty client can access. This includes ...
Using plaintext passwords
Using obfuscated passwords (minimal effort, minimal security)
Encrypted keystore/truststore passwords elsewhere in your client, provided to the SslContextFactory.Client at the last minute. (modest security, wouldn't be that hard to figure out)
Creating the java.security.KeyStore object yourself and handing it to SslContextFactory.Client.setKeyStore(KeyStore) and SslContextFactory.Client.setTrustStore(KeyStore) methods prior to starting the Jetty Client. (a bit better security wise, puts more work on your behalf)
You might want to consider having the client certificates be short-lived (24 hours?) dynamically refreshed from the server, and have the client certificates be revokable (at the server/CA side) if you encounter abuse. (such as the same client certificate from multiple different client IPs)
I'm working on a client / server application. I have connected the two sides via NIO and their connection is secured by SSL. Now I want the server to authenticate the login credentials the user has entered on client side. Unfortunately there is an abundance of contradictory information out there.
This thread Is it ok to send plain-text password over HTTPS? states that
It is standard practice to send "plaintext" passwords over HTTPS.
which makes me think it should be fine in my case too.
Others say
You generally want to use a challenge/response protocol
I want the application to be as safe as it can be. The connection is already protected by TLS 1.2 and SSL but from what I understand this does not make man-in-the-middle attacks impossible which makes me want to implement challenge–response authentication. But this collides with a different server-side security measure I had planned: salting.
This is what I would imagine a protocol that incorporate challenge-response and salting would have to be:
client sends username
server responds with random challenge and user's salt
client hashes password and salt, then hashes it again with the challenge and sends the combined hash to server
server retrieves the correct password hash from a database, hashes it using the challenge and checks the result against the hash the client sent
I have two problems with this protocol.
It sends clients a user's salt before the password has been verified. I know the salt is not secret but it still feels wrong.
Someone could hack a client and exploiting this protocol would enable them to check if users exist and get any user's salt.
EDIT:
Problem 2. can be solved by having the server respond with a random salt in case the user does not exist as Patrick Mevzek pointed out in the comments. That way even a hacked client would not know whether the username or password was wrong.
So I'm all very new to Java and developing for Android, but I somehow managed to get a successful idToken when logging into my app via Google.
I read on the Android dev site that just ID's are not safe as a modified client could send a fake one and result in impersonation of another user, so I followed their steps to get the user's idToken.
Anyway, is this safe to send over a URL to my server at home? For example, like so (pretend the long string of random text is the idToken of the user):
http://130.155.122.8/api_test/h78e568e7g6589gjkdfhjghdjfkghjkdfhgjkdfhk7hg9867458g74598hg6745896gh49/command
Also, is the idToken even required? Could I just as easily use the user's email address to identify the user (again, it would be sent over an insecure URL, no HTTPS)?
Thanks!
You should use encryption, if someone gets the token from a user they can impersonate that user, in my case, since i can't aford ssl (for now) i encrypt the token using asymetric encryption, and i send it to the server, but ssl is the best way
Generally speaking - No.
A token that identifies you should never be transmitted over an insecure connection (e.g. http). Since on such connections no encryption is used, a third party can very easily monitor the connection and get your token (leading to the impersonation issue).
IANAE, but any security-relevant data (e.g. idToken or password) should only ever be transmitted over a secure (encrypted) connection (e.g. https).
And using the e-mail address does not solve the issue. You simply replaced one identifier for another one. And if anyone ever were to know a user's e-mail address, he could impersonate said user. Stick to the "documented" authentication techniques. If done right they should be safe.
In HTTPS (SSL) browser send the encrypted data which can be Decrypted by server only.
To confirm it, i did set up the burp proxy on my Firefox browser so that it intercepts the request sent to HTTPS server by browser .
When i receive it at burp, i see the data as entered by user though i was expecting browser must have encrypted that but did not.
So at what point of time browser encrypt data over HTTPS ?
Most pieces of software that do this (e.g. Anti-virus scanners) replace the https certificate with their own so the https traffic can be man-in-the-middled by the software.
While I'm not familiar with Burp, it looks like it does the same: https://portswigger.net/burp/help/proxy_using.html
So instead of
browser --(via https)--> server
Which only the server could read as only the server has the private key to decrypt the http so, it becomes:
browser --(via https)--> burp -- (via https)--> server
If you look at the https cert in your browser you'll probably notice it's been issued by Burp rather than being the real cert that the site shows when not using Burp.
This is the only real way of doing this, without majorly changing the browser to intercept it before the encryption happens, but can create its own problems: Should software really intercept traffic between you and your bank? What if that first connection can be compromised (see the Lenovo superfish incident for example). Many people (myself included) dislike MITM https services for this reason.
I'm working on a server-to-server authentication via RMI. There's on application-server (server part) and several web-servers (client part) which communicate via RMI. The web-server(s) must authenticate on the application-server. The simplest way would be to use a password which is stored in the web-server's config-file (clear text), but that's obviously very bad practice.
My idea is to use a public/private-key which is generated on the web-server (client). The privateKey is stored in keystore and the publicKey is published to the app-server. To authenticate the client, a generated, random String is signed with the privateKey (create a Signature) and both, the signature und the String are send to the server. The server verifies the String with the signature and it's publicKey. Good idea?
I know this is not very secure but even better than storing clear text password.
Any suggestions for that?
There's no need to make it 100% secure, just a good alternative for password protection.
Thanks and have a nice day.
Public /private key encryption should be good enough.
Other alternatives would be to store the password in an LDAP server and give access to both the server as well as the clients to the LDAP. However, this would add a burden of one more server and some more network usage.
The ultimate security will be to use Secure RMI, this will protect your RMI messages as well as protect the connections to the server.