I need to save user's password to remote service locally. The remote service doesn't support any API for remembering login, so I have to store the password symmetrically encrypted. In fact, I'm making a desktop automation program that literally enters the password into the field.
It's not possible to save locally a password securely - if your program can decrypt it, any other can too. But you can for example make sure that user's settings cannot be decrypted outside of his computer. To do this, people use various hardware/software ID's. I, as many others, elected for MAC address for now. But I was wondering:
Does local Java installation store some constant unique information? Note that Java version is not constant, I meant something like random ID generated during first installation.
Related
This is my first time working on a solo Java project that would generate income from direct sales (meaning I would sell the product instead of a third-party platform).
I was curious as to the following: How can a developer prevent a customer to simply distribute his/her software?
I realize that there are always ways to bypass any sort of security that a developer can put into their project. However, seeing that my product will be run locally (.exe or jar file) there is no way for me to monitor what my client is doing after I sell the product.
Is there a way to put some sort of "illusionary wall" that someone without more advanced knowledge cannot bypass?
Any tips, suggestion or references are greatly appreciated.
I have a server. Some actions within some of my apps will call to the server with some status info. So I know who uses my software. This is plainly stated in the contracts, so no secret stuff.
If I want to limit my software, I do the following:
when my app starts, it collects some system infos and hashes/CRCs them
if there's a matching file, whose contents match the system infos hash, I unlock the app
if there's no such file, or the hash inside it does not match (different system, manipulated, etc) I will (re-)register
registering is either done
by showing the client the hash, forcing him to call/email me, or
the app connects to my server, checks registration infos, shows the page, and then forces user to pay, or unlocks, depending on some other infos i gathered.
on the server side (or manually) I create a key matching the system info hash key
that key gets back into the app (internet or typed manually) and the app checks if that new code matches its system info hash
if keys match, write key to file, and unlock the app
2 downsides:
java is really easy to reverse-engineer:
someone could create a hash generator and create the missing/wrong system info hash file
if you connect through the internet, you should use SSL/TLS, because in other cases, someone could just reverse-engineer (telnet) the answer the app needs to unlock
a good method to prevent reversen-engineering or to make it a lot lot harder is to create pure .exe/elf files. GraalVM native-image is one of those tools that can accomplish such feats. (only using an exe wrapper is rather pointless when it comes to code security, but i good for users)
whenever the client changes things in his hardware, he has to register/reconnect again
All the software i bought for my pc has to be registered once with a license key via internet or has a usb licenser. So maybe this are some ideas something for you. The disadvantages, running a server for product registration or sending an usb-licenser to the costumer. But i'm interested if there are any other solutions
I'm trying to secure a java app that I'm working on. This app has service wrapper that contains a list of parameters, among these a database password. So there are 3 solutions but I'm not sure that any one of them is possible.
1) encrypt the whole file without yet keep it usable.
2) store an encrypted password and add a encryption function to the file
3) create an external program that restores the encrypted password and call it's result in the wrapper.config file
After desperately searching the internet for a response I didn't find any helpful so I'm hoping to find someone who had a similar issue in here.
Another alternative would be to use a key store, as shown in this blog post, however you would still need to find a safe place to store the key to the key store itself. To go around this, you could make your application ask the user the password to the key store, this way the data will be secure but you do not store any (keystore) passwords. That being said, if you are willing to ask your user for a password each time the application switches on, one might as well simply ask the user for the DB password right away.
If you are encrypting the file, you would still need to ship the key with which the application will need to do the decryption. This would mean that potentially users would still be able to look into your application and decrypt the file as they please.
I think that if you really want a safe solution, the answer would be to simply not store the password yourself, but rather ask the users for the password each time.
I'm building an Android app in which I need to encrypt the database. For this I now want to use SQLCipher. I'm now reading about it, but there's something which I don't understand; where does the password reside? Should it be stored somewhere in the Java code, or can the (4 digit) passcode of a user be used to encrypt and decrypt the DB?
And thinking further; what if I have multiple users that can log into the app (I always confirm the passcode with our own API), is it possible to give several users with different passcodes access to the same database (i.e. decrypt it)?
All tips are welcome!
where does the password reside?
In the user's head, or some other place the user elects to store it.
Should it be stored somewhere in the Java code
Not if you want useful security. Anyone can reverse-engineer the app to get the hard-coded passphrase.
can the (4 digit) passcode of a user be used to encrypt and decrypt the DB?
I have no idea what you are referring to. You are certainly welcome to prompt the user for a passphrase. Please do not limit it to a 4 digit value, though, as that can be brute-forced very easily.
is it possible to give several users with different passcodes access to the same database (i.e. decrypt it)?
Not really. SQLCipher only supports one passphrase per database. You can have different databases per user, each encrypted with the user's own hopefully-decent passphrase.
The other day, Google notified me that my Gmail account may have been compromised as it had been accessed by two IP addresses from out-of-the-ordinary locations. Since I generally (and stupidly) use the same password for every website, I decided to change things up and use different passwords.
Being an Android developer, I have decided to start developing a password keeper application for which I can store my usernames and passwords, as it is difficult to remember different passwords. I do not want to take the easy route and download an existing third party password keeper application.
This got me thinking, what is the best way to secure usernames and passwords in my application? Currently, I require a password to view a list of accounts that can be added. I am also storing usernames and passwords into a database. It seems that Android cannot natively encrypt a database, however. I could encrypt the values that I store in the database, but if someone got their hands on my phone, they could find out the encryption if they really wanted to. Or, I could use a server for encryption/decryption, but then you have a server that has to be maintained and can be compromised.
I would love to get some opinions on the topic. While I know that perfection cannot be achieved, what would be a good method to implement for my Android application?
You are certainly going to require the user to provide a PIN or password every time they want to add/view the password list, right? Why not use that as the encryption key, meaning that if someone gets your phone they still cant acces or decrypt the passwords without knowing the user defined key.
take a look at the application 1password they are probably the best password keeper app on the market. Their philosophy is they store all your passwords behind a 128bit encrypthon where you use your 1password to get in. Other than that all website passwords are randomly generated alphanumeric strings. So there is really no collision chance and you are safe where ever you browse.
You shouldn't use a server that just means that people can assume their passwords are sitting somewhere and if you are a good app developer the passwords on the server will be just as secure as if you store them client side.
As for finding out the encryption if they "really wanted to" That is really up to the user picking the one password they key all their information with. Yes, it is possible to crack encryptions with brute force but if the user picks a non dictionary alpha numeric string, the probability of getting through is near impossible. Also if you encrypt everything properly, they cannot just "break" the encryption.
Last just because I can
Credits XKCD
What would be the recommended way for storing passwords in a Java desktop application?
I want the user to have the ability to enter the credencials only once and not be prompted again.
On personal projects I've been using the Preferences API, but I'm assuming this is no different than storing it in plain text (security wise).
Many thanks
EDIT:
Many thanks for your suggestions. There seems to be some confusion, no doubt because I might have not made the question very clear...
I'll give an hypotetical scenario:
Say I'm creating a simple front-end for a remote database which creates a connection string with username/password. Normally the user would be prompted to enter the username/password combination each time the application starts.
What would be the best way to store that password in the user's machine, without the need to re-enter it (connecting automatically upon application start).
A kind of "remember me" functionality (which I know in itself is not a very good practice...)
EDIT2:
Thanks for your answers everyone.
PaĆlo Ebermann's was very informative about the problems at hand and Chris Smith's link was interesting, but I've accepted JVerstry's one, as keystores might be the route I'm taking.
You can use a local keystore where you could put passwords instead of secret keys.
Answer to edit:
Keystores are a perfect fit for your need. If you want extra protection, you could ask the user for one password to access all passwords when the user starts the application. Then, you could protect stored database password with a simple salt-and-stretch method (to generate an encryption key) using the one password that was used when starting the application.
There is no way to store something on a computer in a way that your Java program can retrieve it (without the user entering some password), but no other program (running in the same user's account) on this computer can retrieve it.
You can try to encrypt it somehow and hide the decryption algorithm together with the decryption key in your program (white-box cryptography), but then the attacker just needs to run your program in a debugger to let it decrypt the data.
You could use the system's permission system, but this will usually not help if the attacker is some program running in the same user account as your Java program (and would help even less if the attacker has root access).
The best bet would be to store the password on a USB memory and tell the user to take it out when you are done using it, but if the attacking program is running and observing while you are reading the secret from the stick, even this does not help.
Regardless of the language, I think this applies: http://codahale.com/how-to-safely-store-a-password/
In summary, use a bCrypt hash function.
The preferences API is implementation dependent from memory so you will be at the mercy of the JVM vendor. If it's a Sun/Oracle JVM, it's trivial to get at the data. If you hash it and enforce a decent password policy however, it will be very safe. The original password will be very hard to determine.