I have a java program that scraps web pages and store data on a db.
This program has no user interface, it's run vy the linux boot sequence.
what is the best way to store the db and sites password for a program like this?
I alreasy tried pass them via configuration file or command line, but i'm not very satisfied.
Thanks
You can use some secure keystore or wallet, but the bottom line is, as long as an attacker gains access to it, they can simply alter the script to print out the credentials.
Since your system consists of at least 2 components (script, db), you have to think of security on the level of the whole system. E.g. it doesn't matter if you put the cleartext passwords in the script if your system is not accessible externally by any means. On the other hand, you can have the best encryption and anti-tracing techniques, and yet, by simply setting up a proxy between your software and the DB software, one can scoop the password.
There is no simple answer for this. Sysadmins generally put the password in the script and make it 700.
Here is an excellent article that might help: Codinghorror
Generally I would say: Put restrictive chmod rules & salt, salt, salt !
Unless you deal with very sensitive data such as Banking. I would say don't worry about it.
Do your best to secure the server itself.If you don't want to expose the password in config file. Then create a class for your java program that will hold them.Then compile the code.
No matter what you do, you will still have to type in the password somewhere.
Related
I am developing a java swing project that require login and password that need to be entered when run first time i.e. setLoginFrame.java.
for all the subsequent run it should run the Login.java
can't find a way other than file handling to store login and password..
I have no idea like how to do this..
If it's not very risky data, then you can just use files for storage, then encrypt them separately if you wish.
Else, you can generate hashes of your strings with MessageDigest in the java.security package. Just call getInstance() as per the example. SH1 is generally seen as stronger encryption.
You really should learn about security of data and how to store passwords.
If you want to store data, there is always a database option.
But if you are staying with storing in files, there is a lot of info in the web about how to do so. For example here.
For example,
Gmail Login->enter invalid username and invalid password and click login button,if i give invalid credentials it should display the error msg as "Invalid USername or Password".How to verify that the given credentials is correct or notand how to verify that i have logged in successfully??
Most systems require the user to change the password from time to time. It makes Stultuske 's suggestion highly unstable because the credentials for a account SURELY WILL change. And even if your system do not require it, writing passwords is highly error-prone.
You are doing Data-Driven Testing, so, you should store all your data in only place, not spread that across your test cases by hard-coding it.
A simple structure as a YAML file should be fine for you.
Most languages have libraries to work with this data. Ruby and Java, e.g.
Let me give you an example; see this gist:
https://gist.github.com/JoaoGFarias/581159a3478ed4e8f65e
As you can see, if ever any password change, you only need to update the users.yml file, which is very simple.
Hard-coding is not a good thing in development and it's is not in Automation (because, let me tell you a secret: Automation is software development, same way - people often think it's not, but they are wrong).
I am maintaining an existing Java product (which has a HUGE code-base). I discovered that it is setting (and getting) two of its internal passwords as Java system properties, at no less than 4-5 different places (methods). Now, the problem is, the passwords are being stored as plain text in the Java system properties, and so, the same is visible to external entities, as the application is not using any Java Security Manager. For example, if the application (process) is running on port number 1234, we can run the Java command:
jinfo -sysprops 1234
to view both the passwords as values of the corresponding Java system properties. I wish to ask if there is any remedy to this without changing the existing code-base too much? The desired effect would be to "hide" the two Java system properties (denoting the two passwords) from all external entities.
It may be noted that introducing a Java Security Manager into the application may not be a solution, as if we revoke read permissions from the said two Java system properties using the Java Security Manager, the application codes which read those properties would crash. Same is applicable for storing the passwords in encrypted form, as that would crash all codes within the application which are expecting to read the passwords in clear text form.
Since you said:
...at no less than 4-5 different places...
and you really don't want to do major code changes, I would:
Supply the password in an encrypted form.
Go through those 4-5 places (it's not so much!), and call a wrapper method that you have to write separately: MyPassUtil.getXYZPassword() which internally calls the System.getProperty() to get the encrypted password, decrypt it, and return the plain text version to whoever is calling it.
Keep in mind though, that this way, the decryption key and algorithm is stored within the application, and a good Java decompiler (JD-GUI or CFR) will still return this information. In other words, anyone with the access to the JAR file, can still get the information with some minor effort, something which I presume, since one can call jinfo, they can also get the JAR file.
The best is to use some form of keystore, which again, you can easily implement once you do the wrapper method mentioned in step 2, without affecting whoever is using it.
Also, some security tips:
If it's an SSH / SFTP connection, set up SSH keys between the two machines, and eliminate use of passwords.
If it's a database connection, at least configure the DBMS to allow connections only from this particular machine's IP address. If the connection is over the internet and you are behind an NAT, set-up a VPN first, and channel the traffic between the hosts through it.
For other setups, try and see whether there are some other tips you can do similar to these two points, to improve the security around these passwords.
I'm currently working on a project in which I need to keep the user's files encrypted. This part I've achieved easily by using Java's built-in cryptography library. Loading the file from the disk is done by reading the salt from an attached file, having the user input the password, and then generating the salted and hashed key, which is then quickly disposed. But when it comes to saving the files back to the disk, a problem arises because I need to keep the key in memory throughout the whole runtime, or have the user input the password every time I write the file to the disk. What would you recommend in order to keep my application as secure as possible.
To be as secure as possible then your user should enter the password again. However really you need to look at the use-case and decide what you are defending against.
For example if they have to enter the password again then they are more vulnerably to someone shoulder surfing or key loggers, etc but the increased risk is pretty small.
The password kept in memory is only vulnerable to processes already running on the machine the software is running on. That again is a pretty small risk as it would probably be easier just for them to put a key logger on.
So really in this sort of scenario the main risk factors are the people. Can someone trick the person entering the password into revealing it (i.e. spear fishing, fake login prompts, key loggers, shoulder surfing). Mitigating most of those risks is about training, not about technical issues at all.
Far too many people think that a technical silver bullet can solve all their security woes. It really can't, a system is only as secure as its weakest link and you need to think about the big picture as well as the small one.
Currently i include
jvmArg=-Djavax.net.ssl.keyStore=/cfg/secret
jvmArg=-Djavax.net.ssl.keyStorePassword=123456 a.b.c.Proxy
What would be the alternative notation where password is not stored in clear text?
You would have to build an X509KeyManager manually and initialise it by loading a KeyStore programmatically. When loading the keystore, you call its load(...) method which will take a password (you could use a callback if necessary).
If you want your application to run unattended, you password will be obfuscated at best, not strongly encrypted (since your application will need to be able to decrypt it when required without a further password). It can be worth the effort, but not always (since an attacker may just be able to get that obfuscated version and de-obfuscate it easily).
(One of the problems with JVM args is that they may be visible in the process argument list, depending on your environment. Setting the system properties within your application when it starts might help in some cases.)