Secure password storing while authenticating to JIRA via SOAP service - java

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.

Related

Java spring boot encrypt admin password before storing it in database?

I require an admin user to be initialized in the database because to register a new account admin permission is required. The problem is when I enable encryption (encrypt all registered users passwords), it also tries to decrypt the initialized admin password and returns error:
Encoded password does not look like BCrypt
I am thinking I can somehow encrypt the initialized admin password before storing it in the database (MySQL). But I am unsure of how to go about doing this. Any tips?
Currently, I am initializing the database with the admin user by using SQL queries.
In this case you should override you old plain-saved password by the encrypted one directly in DB. Or drop and recreate your account according to new rules
To do this you can type your plain password to site like this
https://www.browserling.com/tools/bcrypt
set round to 10 (this is value that Spring bean uses by default)
and it will give you encrypted password. just replace it in DB
IMHO, I am not sure if MySQL has a default BCrypt encryption function. I guess that you have the bcrypt installed in your machine which you are using for the passwords to be encrypted. If that is the case, I would not recommend using the database-level encryption.
I think another problem with the database level encryption is, the data you are passing to the database, might end up stored in the database log or server logs. Hence, you might lose the confidentiality of the passwords.
If I had to design the system, I might have gone for the application-level encryption and would let the Spring-Boot application to handle this.

Add encryption to JDBCLoginService in Jetty

I've configured servlet, and other things needed to have role-based access to resources. I'm using JDBCLoginService to access roles data from DB. All works great, my only problem is: how to configure Jetty that in database I'll have passwords encrypted (preferably not MD5).
I found several docs saying you can run some tool given by jetty and it produces you MD5 or OBF, etc. But I wonder how to get list of avail ciphers?
I believe in table with users, column with password should have something like "MD5:897897979".
But I want to add users to this table by functionality like register/signup. So I need to encrypt password sent from browser and put to DB. But I can't control algorithm which is used by JDBCLoginService to check data sent by user from login page.
I believe it's implemented in some smart way that not much extra code is needed, but I can't just find info how to do it :/
I had a similar problem and tried to resort to the facilities provided by the Password class in the Jetty distribution.
However, eventually I couldn't adopt that approach since I was in need of storing the passwords hashed with a specific algorithm (namely sha256 or sha512) and I couldn't find a way to get the JDBCLoginService work with such hash algorithms.
This was kind of a let down, especially because Tomcat comes with the support of those algorithms out of the box when it comes to handle database-backed authentication scenarios.
I found this problem today. And the solution I ended doing is to have the sha256 calculated for the password input field in the browser side. You can do it on form submit or any other event if you are careful not to re-hash. Simple check or password length less that 64 would be sufficient to avoid rehash. I used the below to do the hash
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
Paradoxically this solution makes it stronger as the password is hashed from the browser itself. Of course it could be exploited from this same web app but not in others that do not use hashing from browser if the is is used for other authentications.

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.

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