Storing passwords for batch jobs - java

I have a little java prog that uses a webservice which needs authorization. So the java prog (which is to be run using windows task scheduler) needs to have a user/password argument. How can I store these somewhere without having them laying around in a file as plaintext?
So far I've tried using runtime.getRuntime and CACLS to have a plaintext file but alter the permissions so only the owner could open it (didn't work, not sure why).
Password encryption doesn't work because if I pass the hash to the webservice, the webservice is just "errr what? denied, get lost", but if I use secret key encryption you need a password to decrypt the password. and where do I store that. :P
Help? Please? :)
Thanks.

The simple answer is:
You can't make it entirely secure but you can make it marginally more secure.
You CAN NOT hash the password because this would prevent it's use by your program.
You CAN put the password in a file and protect the file using the OS permissions. You will need to allow the process executing your program read access. This prevents anyone without administrator rights from viewing the password.
You CAN encrypt the password and provide the key in your program. This prevents casual observation of the password by those who can read the file but will not stop (or even slow down much) someone with access to the password and your program.
Anything else is more or less theater.

how can i store these somewhere without having them lying around in a file as plaintext?
Storing without a "file" will be dificulty. Anyway at some moment you have to retrieve the password from some location.
Use some symetric encryption for
obfuscating so a quick hash does not
reveal your password
Use the OS filesystem (read-only for the user
that uses the program, no access all
other) to protect the file on local disk or put it on an external drive (flash).

There's no way that you can keep your password safely if someone has authority to access that running machine. Keeping the password encrypted somewhere in memory is the most secure way I think, just like the run-as-service solution above proposed.
For a more sophisticate approach, you can create a daemon which allows you to key in the password, keep it encrypted in memory, and passes that encrypted text to your java program via IPC (socket), then you program will decrypt it to use. But I would never do this... Hihihi...

Two questions:
why do you need to store them externally to the program ? Why not encode within your Java program (do you or the user need to change them?)
Can you store them externally, but encrypted ? For instance, you can encrypt using a public key, and store the private key within the program itself. So visibility of the encoded pair shouldn't matter.
You have a problem regardless of either approach, in that you can easily disassemble a Java program. Whichever method you choose, disassembly will make it vulnerable.

An option is to not use the Windows task scheduler, but rather put your program as a service. Doing so, you can launch your service once with the password as a parameter. Then the password stays in memory for your service and you don't need to store it anymore.
Setting the program as a service can be done quite easily with the Java Service Wrapper

Related

Apache Kafka hiding Keystore passwords in properties file [duplicate]

I need to set the following variables before invoking remote queue.
System.setProperty("javax.net.ssl.trustStore","C:\\certs\\trustStore.jks");
System.setProperty("javax.net.ssl.keyStore","C:\\keystore\\keyStore.jks");
System.setProperty("javax.net.ssl.keyStorePassword","Demo1234");
System.setProperty("javax.net.ssl.trustStorePassword","Demo1234");
The passwords are exposed here. What is the best way to encrypt the passwords?
At some point, your private key/key store password must be visible to enable secure communications to take place. It needs to be stored securely within your web/app server. And your code base needs to be securely stored and only accessible to the people who need to see it. You could store it encrypted somewhere and decrypt it for use, but your encryption and decryption algorithm would still be visible and potentially emulated, so at some point, the means to access the clear text will be available and it's merely a matter of ensuring that it's only available to as few people as possible and kept from prying eyes as far as possible via your network security.
Encryption technique here, if you need it: How to encrypt String in Java

Storing sensitive infomation

One of my java class will connect to a another server and do some operation using rest services. Java class requires - username and password to connect to remote server. On other machines we used to store the credentials using oracle cwallet.sso but this is not an option for current machine. I am thinking to store the encrypted password in properties file adding some salt. I also need to store the key and salt string to some secure place. do we have any alternative in RHEL for password management like cwallet or any suggestions what to should be the best way to achieve this?
Please note that I will invoke this class using shell script.
Thanks
This is tricky, because if someone gets access to your server is already game over. So the solution is not just to encrypt the data, as it won't do much, but you need security in depth.
To put this in context, you can have the password encrypted, salted whatever... When an attacker gets access to the server, he won't be able to read any of those files (even with the encrypted password) unless he is able to become the user running the app. If he manages to do that, he only needs to do a memory dump and then fish for passwords (which is not hard).
So a real world solution is:
Only allow a restricted number of people to log on the server.
Only allow an even smaller number to become the user which runs the application server.
This group of people are the ones who can read/update the properties file
Disable any kind of backups on the files that contain secrets.
Again, encrypting passwords on the files might give you a sense of security, but again, if you follow the steps above, anyone who can read the file, will also be able to read the memory contents of the app. And even if someone does things right and stores that password in an bit of offheap memory, some linux tools can read the whole memory map of a process, so again, game over.
Using encryption in this case just adds obscurity and no real protection.

Externalize Credentials from Flat Java

I have a flat java file that's querying two databases and currently has the credentials hardcoded. The plan is to convert this to spring batch but in the mean time I would like to encrypt them within a config/properties file externally and call them. I'm looking for any specific examples, best practice / solution. I appreciate any time and effort. Thank you!
If you decide to encrypt the credentials, then you have the problem of secure storing the encryption key. The best you can do it to not store it at all and require it to be given manually whenever your application starts up. Your application should use the key to decrypt credentials, connect to any services. Finally it must throw away the key and credentials after use, in order to prevent getting them from memory.
If manual intervention during application startup is unacceptable, then a typical solution is storing the key in a file with appropriately restrictive permissions on an encrypted partition, but if the system gets compromised, e.g. an attacker somehow gets root privileges or privileges of your application, he will be able to recover the database credentials.

Secure password storing while authenticating to JIRA via SOAP service

I am writing an application, in Java, which needs to log in to a remote SOAP service (JIRA) prior to calling methods on that service.
I have looked at examples of how to do this, for example http://www.j-tricks.com/1/post/2010/8/jira-soap-client.html, however I am concerned that I need to put the password in memory at some point.
I've read that I should store the password as a char[] but still, I'm concerned about storing the password in the clear at all.
How should I store the password used by my client to log into the SOAP service? And how should I read it and pass it to JIRA?
EDIT
This application will be using Spring so it's likely the password would be stored in the bean configuration file rather than in the code.
The SOAP login method returns a string token you can use for the session, so there's no need to store the password in memory after using it. But I think you're talking about longer term usage. Applications will usually have a configuration page to allow a more permanent authentication to be set up, and then require a password to be entered each time that connection is reconfigured.
Here's what I decided on eventually.
First, some clarifications.
The password is encrypted and stored in a database.
The password is statically populated (by the DBA).
This is an exercise in encryption and decryption, therefore hashing algorithms, such as MD5 are not applicable.
I looked into ways of encrypting in SQL and decrypting in Java, but none were particularly good. Therefore I decided upon the following approach.
When the DBA populates the password, they run the DBMS-specific encryption method (e.g. MySQL's encrypt) when entering the password (e.g. insert into creds(user,password) values ('bob',encrypt('password'));
The SQL to retreive the password, passed to the spring application as a property, includes the decryption (e.g. select user,decrypt(password) from creds).
Other than that, this is an exercise in user management and locking down the database. E.g. only certain people (DBAs) get full access and the application uses a read-only user.
Hope this helps someone else in the future.

Email account password storage in Java/Mysql server program

I am in a sticky situation where I am writing an application that sends out emails to clients using an email account of my company. The issue here is that I have to have the password for the account to make the mail service on the server send out emails from that account. I know that passwords should never be stored in plain text, particularly ones that are used for an important email account. The dilemma here is that the program NEEDS to have the actual plain text password to send the emails so it needs to be stored somewhere accessible by the program. The program uses a MySQL database to store information so there are three options in my mind:
1) Store the password in the program's memory, i.e. a private final String field.
2) A file on the on the server where the password can be read from
3) Somewhere in the MySQL database.
I would think that 1 is the safest option, but does anybody have ideas to handle this sort of situation to minimize risk of the password falling into the wrong hands? Thanks for your advice!
The comments pointing out that SMTP doesn't require authentication are correct. That said, all three of the options you specified are insecure, assuming that the server uses commodity hardware and software. I'll show why each is insecure, although I won't follow your original order.
2) A file on the on the server where the password can be read from
3) Somewhere in the MySQL database.
What if someone were to steal the server? Then, they could just open the file or the database, read the password, and immediately have access to all the important information in the company. So unless you have armed guards surrounding the server day and night, this is already pretty insecure.
But it gets worse. No computer system is completely invulnerable to attack, and several well-publicized attacks (Sony's PlayStation Network, for example) in the past few years have shown that an attacker can get to the contents of disk files and databases without physical access. Furthermore, it seems from your question that the server in question is meant to accept packets (HTTP requests, incoming emails, etc.) from the outside world, which boosts your attack surface.
1) Store the password in the program's memory, i.e. a private final String field.
This is tempting, but this is even more pernicious than option 2 or option 3. For one thing, a private final string field is stored in the .class file generated by the Java compiler, so with this option you are already storing the unencrypted password on the server's hard drive. After compromising the server as in option 2 or 3, an attacker can just run javap in order to get the plaintext password out of the .class file.
This approach broadens your attack surface even more, though. If the password is stored as part of the source code, suddenly it's available to all developers who are working on the code. Under the principle of least privilege, the developers shouldn't know extra passwords, and there's a very good reason here. If any of the developers' machines is stolen or compromised from outside, the attacker can look through the compromised machine's hard drive and get the plaintext password. Then there's source control. One of the really important benefits of source control is that it allows you to inspect any prior version of your code. So even if you switch to a secure method in the future, if the password has ever entered source control then the source control server is a potential attack point.
All of these factors add up to show that, even if the HTTP/mail server's security is top-notch, option 1 increases the attack surface so much that the HTTP/mail server's security doesn't really help.
Extra detail: At the beginning I specified "assuming that the server uses commodity hardware and software." If you aren't using commodity hardware and software, you can do things like boot from readonly storage and use only an encrypted database, requiring a person to provide the decryption key on every boot. After that, the decrypted information lives in memory only, and is never written to disk. This way, if the server is stolen, an attacker has to unplug the server and so loses all the decrypted information that was only ever in memory. This kinds of setup is sometimes used for a Kerberos KDC (with the server in a locked boxe for extra security), but is rarely used otherwise, and is frankly overkill when there is an easy way to solve your problem without going to all this extra expense.
If you were serious about keeping it safe, you could encode the password and put it in 2 or 3. When you need to use it, simply have your program decode it and save it in memory as a plain string.
ex.
String encodedUrl = URLEncoder.encode(url,"UTF-8");
String decodedUrl = URLDecoder.decode(url,"UTF-8");
This is a common problem. You can store the password in MYSQL in a blob field applying AES encryption on the insert; using and keeping the key_string in java for handy decryption.
MYSQL Syntax :
AES_ENCRYPT(str,key_str)
and
AES_DECRYPT(crypt_str,key_str)
The insert would be similar to the following:
INSERT INTO t VALUES (1,AES_ENCRYPT('password','encryption_key'));
You would use the key to decrypt coming out
SELECT AES_DECRYPT(password, 'encryption_key') AS unencrypted FROM t
So you never store the password as plain text in your application although you will need the encryption key. Your connection to the database should be secure. Logs may be an issue.
Alternately you could use stored procs to get the keys in and out or you could encrypt them server side and insert/retrieve after encrypted.

Categories