Anil Saldhana is the Lead Identity Management Architect at JBoss. He blogs at http://anil-identity.blogspot.com Anil has posted 16 posts at DZone. You can read more from them at their website. View Full User Profile

Security Features of JBoss AS 5.1 - Part 2 - Masking Passwords in the configuration files

06.12.2009
| 27381 views |
  • submit to reddit

Nobody likes the idea of seeing passwords in the open in an xml file.  In JBoss AS, we have various mechanisms by which passwords can be masked in the xml file. This article will act as a single stop reference to the various mechanisms.

In order to mask password attributes in the JBoss Microcontainer Bean definitions, see the following prototype

 https://jira.jboss.org/jira/browse/JBAS-6710

... which works for JBoss AS 5.1 onwards

 

Disclaimer:

With the use of passwords, no system is 100% secure. One mitigating approach in a password based system is "security by obfuscation". This is what we use in this method. We use a certificate and a secret key to mask the password for a particular security domain.

 

Steps to perform

First you need to create a keystore and generate a key (See additional information below for example). Remember the keystore location should match with the attribute configured in your JBossSecurityPasswordMaskManagement defined in deploy/security/security-jboss-beans.xml

 

You can use the command in the bin directory.                                              

  1. Use the Password Tool (mentioned below).
  2. Configure the @Password annotation on the MC beans that you are interested in masking the password. Example is provided below.

 

Password Tool

There is a command line tool that can be used for centralized password management.  The script is located in the bin directory. Remember that you can use the tool in the bin directory and the server configurations (default, all etc) can make use of the files that are generated by this tool.

=============================================

anil@localhost:~/jboss-6.0/jboss-head/build/output/jboss-6.0.0.Alpha1/bin$ ./password_tool.sh
**********************************
**** JBoss Password Tool********
**********************************
Error while trying to load data:Encrypted password file not located
Maybe it does not exist and need to be created.
0: Encrypt Keystore Password 1:Specify KeyStore 2:Create Password
3: Remove a domain 4:Enquire Domain 5:Exit

0
Enter Keystore password
testpass
Enter Salt (String should be at least 8 characters)
AnyStringThatIsLong
Enter Iterator Count (integer value)
111
Keystore Password encrypted into password/jboss_keystore_pass.dat



Loading domains [
]
0: Encrypt Keystore Password 1:Specify KeyStore 2:Create Password 3: Remove a domain
4:Enquire Domain 5:Exit
2
Enter security domain:
messaging
Enter passwd:
myPass
0: Encrypt Keystore Password 1:Specify KeyStore 2:Create Password
3: Remove a domain 4:Enquire Domain 5:Exit
5
org.jboss.security.integration.password.PasswordTool$ShutdownHook run called
Storing domains [
messaging,
]

=====================================================================


 

Configure the MC Beans

You will need to add an annotation to the bean definition.  Lets take the example of JBoss Messaging SecurityStore MC Bean defined in deploy/messaging/messaging-jboss-beans.xml

 

Before your modification:

 <bean name="SecurityStore" 
class="org.jboss.jms.server.jbosssx.JBossASSecurityMetadataStore">
<!-- default security configuration -->
<property name="defaultSecurityConfig">
<![CDATA[
<security>
<role name="guest" read="true" write="true" create="true"/>
</security>
]]>
</property>
<property name="suckerPassword">CHANGE ME!!</property>
<property name="securityDomain">messaging</property>
<property name="securityManagement">
<inject bean="JNDIBasedSecurityManagement"/></property>
</bean>

 

After your modification:

 <bean name="SecurityStore"
class="org.jboss.jms.server.jbosssx.JBossASSecurityMetadataStore">
<!-- default security configuration -->
<property name="defaultSecurityConfig">
<![CDATA[
<security>
<role name="guest" read="true" write="true" create="true"/>
</security>
]]>
</property>
<property name="securityDomain">messaging</property>
<property name="securityManagement">
<inject bean="JNDIBasedSecurityManagement"/></property>
<!-- Password Annotation to inject the password from the common password
utility -->
<annotation>@org.jboss.security.integration.password.Password(securityDomain=messaging,
methodName=setSuckerPassword)</annotation>
</bean>

 

As you can see, you have removed the attribute called as "suckerPassword"   and introduced an MC annotation called as @Password whose configuration includes the security domain as well the MC bean property where the password needs to be injected.

 

 

Additional Information

The keystore can be generated as follows:

Here we are running it in the bin directory of the JBoss AS installation.  The Keystore will be created in directory password. This will match with the deploy/security/security-jboss-beans.xml bean definition as stated above.

 

$ keytool -genkey -alias jboss -keyalg RSA -keysize 1024  -keystore password/password.keystore
Enter keystore password: testpass
What is your first and last name?
[Unknown]: JBoss Security
What is the name of your organizational unit?
[Unknown]: JBoss Division
What is the name of your organization?
[Unknown]: Red Hat Inc
What is the name of your City or Locality?
[Unknown]: Raleigh
What is the name of your State or Province?
[Unknown]: NC
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=JBoss Security, OU=JBoss Division, O=Red Hat Inc, L=Raleigh, ST=NC, C=US correct?
[no]: yes

Enter key password for <jboss>
(RETURN if same as keystore password):

 

Other Masking Information

  1. Encrypting Data Source Passwords
  2. Encrypting Keystore Password in Tomcat Connector
  3. Encrypting Ldap Password in the LdapExtLoginModule

 

Background Information

This feature utlizes the Microcontainer lifecycle callbacks.

 JBoss MC Deployment

 

 

The password is set from a common utility into the MC bean during the "create" step.

 

Reference:

  1. http://www.jboss.org/community/wiki/MaskingPasswordsinJBossASXMLConfiguration
  2. http://server.dzone.com/articles/security-auditing-jboss

 

Troubleshooting

  • Ensure that the keystore generated (by default it should be password/password.keystore) is the same as the one defined in deploy/security/security-jboss-beans.xml
  • Did you comment out the suckerPassword attribute in deploy/messaging/messaging-jboss-beans.xml and enable the annotation for Password there?

 

About the Author:

Anil Saldhana is the lead security architect at JBoss. He blogs at http://anil-identity.blogspot.com

AttachmentSize
MCDeployment_compressed.png73.09 KB
Published at DZone with permission of its author, Anil Saldhana.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Oleg Gryb replied on Tue, 2009/11/24 - 5:22pm

 

I've checked how password_tool encrypts/decrypts the data and found out that the same hard-coded PBE secret (78aac249a60a13d5e882927928043ebb) is used for encrypting/decrypting (see below).

Please let me know what I'm missing here or what is the point of the whole proposed solution? If my findings are correct, it will just create a false feeling of safety.

From FilePassword.java:

124      static char[] decode(RandomAccessFile passwordFile)
125   throws Exception
126   {
127   byte[] salt = new byte[8];
128   passwordFile.readFully(salt);
129   int count = passwordFile.readInt();
130   ByteArrayOutputStream baos = new ByteArrayOutputStream();
131   int b;
132   while( (b = passwordFile.read()) >= 0 )
133   baos.write(b);
134   passwordFile.close();
135   byte[] secret = baos.toByteArray();
136  
137   PBEParameterSpec cipherSpec = new PBEParameterSpec(salt, count);
138   PBEKeySpec keySpec = new PBEKeySpec("78aac249a60a13d5e882927928043ebb".toCharArray());
139   SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEwithMD5andDES");
140   SecretKey cipherKey = factory.generateSecret(keySpec);
141   Cipher cipher = Cipher.getInstance("PBEwithMD5andDES");
142   cipher.init(Cipher.DECRYPT_MODE, cipherKey, cipherSpec);
143   byte[] decode = cipher.doFinal(secret);
144   return new String(decode, "UTF-8").toCharArray();
145   }
146   static void encode(RandomAccessFile passwordFile, byte[] salt, int count,
147   byte[] secret)
148   throws Exception
149   {
150   PBEParameterSpec cipherSpec = new PBEParameterSpec(salt, count);
151   PBEKeySpec keySpec = new PBEKeySpec("78aac249a60a13d5e882927928043ebb".toCharArray());
152   SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEwithMD5andDES");
153   SecretKey cipherKey = factory.generateSecret(keySpec);
154   Cipher cipher = Cipher.getInstance("PBEwithMD5andDES");
155   cipher.init(Cipher.ENCRYPT_MODE, cipherKey, cipherSpec);
156   byte[] encode = cipher.doFinal(secret);
157   passwordFile.write(salt);
158   passwordFile.writeInt(count);
159   passwordFile.write(encode);
160   passwordFile.close();
161  
162   }

Anil Saldhana replied on Wed, 2009/12/09 - 11:26pm

Since when did I say that this is impregnable. Our objective is to mask clear text password and that is what we are trying to achieve without adding additional complexity.

Oleg Gryb replied on Tue, 2010/03/30 - 10:14pm

Well, what you didn't say is probably more important than what you did say. If you had written on the first page of your solution that a hard-coded public token is used to encrypt the password then I and many other developers would not have spent their time on reading the rest of it.

The bigger problem is that  some developers do take the solution seriously and start using it to encrypt their production secrets. The best outcome of that is when a security auditor finds it first, the worst - when bad guys do the same.

Security is not equal to obscurity.

Anil Saldhana replied on Tue, 2010/04/13 - 3:52pm in response to: Oleg Gryb

Security by obfuscation.

There is no 100% security when you use passwords.

Oleg Gryb replied on Fri, 2010/04/30 - 1:51pm in response to: Anil Saldhana

There is no 100% security in any system. That's not the point, the point was that the solution adds too little security (if any) to storing secrets, it's probably in the same category as XOR-ing sensitive data with something or just like yet another password encrypting solution provided by JBoss and described here: http://community.jboss.org/wiki/EncryptingDataSourcePasswords

Shamir Secret Sharing algorithm would be more appropriate for this case in my opinion:

http://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing

It simply implements a well-known "k of n"  principle and can be be very secure if implemented properly.

If would be great if JBoss addopts this approach in the future.

Anil Saldhana replied on Mon, 2010/06/14 - 4:21pm

Oleg, I understand your concern. We are saying "masking" passwords and not "encrypting" passwords. 

This particular article uses a key to encrypt the password and then uses the keystore certificate to encrypt it again before storing in the file.

We will take a look at the wiki article that you refer to.

hp slayer replied on Tue, 2010/09/21 - 10:03am

Hi Anil, Is there a way where you can mask passwords in properties file such as jboss-web.xml , you need to put passwords in it if you are a web services client calling a secured webservices e.g given below. <?xml version="1.0" encoding="UTF-8"?> service/HelloService com.sample.HelloEJB javax.xml.ws.security.auth.username YYYYYY javax.xml.ws.security.auth.password XXXXXXX

Liezel Jane Jandayan replied on Thu, 2011/08/25 - 7:05am

JBoss itself is open source, but Red Hat charges to provide a support subscription for JBoss Enterprise Middleware. Before November 2010 JBoss was licensed as annual subscription in bundles of 4 and 32 CPU sockets. As of November 2010 the licensing changed and all cores on the system are now counted. The core bundles licensing is available for 16 and 64 cores.-Jonathan Berkowitz

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.