Index Changes

Difference between version and version     

Back to Systemic Qualities.Password Handling, or Systemic Qualities.Password Handling Info

At line 1 added 4 lines.
!!!Requirements and Analysis
At line 37 added 223 lines.
!!! Design
!! Overview
Password handling at all stages of the development of an application is extremely important. For obvious security reasons, passwords must be kept safely masked and/or encrypted. This design document seeks to provide a combination of components and best practices that will enable JBI Components to handle passwords in a consistent manner in JCAPS and OpenESB. Areas that will be addressed include
* Tooling requirements and components in the Netbeans 6.0, Command-Line Interfaces, and Web-based Administration GUIs
* Runtime requirements and components for handling passwords and storing passwords securely for Glassfish V2 in both a clustered and non-clustered environment.
While this may seem obvious, we must define what a password is. A password is anything that we want to be masked so that a user cannot view it, either through a GUI or in a persistent data store. Examples of passwords might include
* External system passwords (i.e. Databases, Applications like SAP, Siebel)
* Passwords can be embedded as part of the application in application artifacts (i.e. WSDLs)
* Passwords can also be associated with the component and updated through a component's configuration interface. In most cases, this is some type of Mbean editor.
* Passwords are entered by users through some type of tooling. The tooling must keep the passwords secure through masking and/or encryption.
* Passwords are used during the running of the application and component.
!Key Requirements
This section provides a brief overview of the key functional requirements of the component or system to be developed.
|PH 1 |Passwords cannot be in clear text in any application artifacts
|PH 2 |GUI-based tooling cannot reveal plain-text passwords
|PH 3 |Passwords must be stored in an encrypted fashion
|PH 4 |The runtime processing of passwords must not allow the password to be revealed in clear-text at any point.
!!Technical Description
! Component Architecture
The core classes will address each of the key requirements in the following manner:
# PH1 โ€“ Passwords will not be allowed to be embedded in application artifacts. They will be exported using the environment variable design. This design will not be detailed in this document.
# PH2 โ€“ A schema will be provided that details the configuration of the component. This schema will be available to all tools to discern what fields need to be masked. (This strategy may change in the future and has not been completely flushed out.)
# PH3, PH4 โ€“ The JBI Framework will provide an implementation of KeyStoreUtil which will allow components to encrypt and decrypt strings. It is up to the component to properly use the utility on all fields that are designated as passwords.
! Structural Models
The class role descriptions below describe what each class/interface's responsibilities.
The KeyStoreUtil interface provides methods for creating, updating, deleting, and reading keys from a key store. The interface also provides utility methods to encrypt and decrypt strings based on the name of the key. The interface makes no restrictions on where the key store is located. Other than the encrypt and decrypt methods, the interface makes no other restrictions on how the key store will be used
The SunASKeyStoreUtil is an implementation of KeyStoreUtil. It uses the underlying PasswordAdapter class provided by the Glassfish Application Server to generate and store keys. Encryption and decryption capabilities are provided by the javax.crypto.Cipher class.
The ComponentContext interface details extensions provided by the JBI Framework. There is now the addition of a getKeyStoreUtil() method which Component developers can now call to get an instance of KeyStoreUtil
The ComponentContext class provides the implementation of com.sun.jbi.component.ComponentContext. With regards to the getKeyStoreUtil() method, this implementation should delegate the work to the PlatformContext.
This PlatformContext interface provides a set of common methods that a particular platform needs to provide for the JBI Framework. With this initiative, we've added a new getKeyStoreUtil() method.
__SunASPlatformContext, JSEPlatformContext, WebSpherePlatformContext__
These three classes are implementations of PlatformContext. They will all include the new getKeyStoreUtil() method.
! Behavioral Models
Encrypting a string
! Interfaces
Exported Interfaces
Interface Name
Proposed Stability Classification
Former Stability Classification
[Provide a reference to the actual interface]
Imported Interfaces
Interface Name
Proposed Stability Classification
Former Stability Classification
[Provide a reference to the actual interface]
Implementation Considerations
Persistence of Keys
Implementations of KeyStoreUtil should obfuscate keys when storing them in a KeyStore
Persistence is assumed to occur immediately and atomically with each of the Create, Update, and Delete operations for keys on KeyStoreUtil
Clustering synchronization
(Need input from Keith Babo)
Client considerations when using KeyStoreUtil
The KeyStoreUtil interface is very simple and basic. However certain considerations need to be addressed in obtaining this interface and using it. These questions should be considered in providing a client-side library:
1.If the framework does not provide an implementation of this class, what should the client do? Should the client fail, use another utility, or simply expose the passwords in clear text?
2.Getting the KeyStoreUtil interface from the framework requires casting to an interface specific to the JBI Framework. This limits portability of our components. Can we fix this in some way?
Limitations of interfaces
The KeyStoreUtil class has methods for encyrpt/decrypt. These methods do not allow the use of additional attributes for further configurability. This was done on purpose to limit flexibility and increase ease of use.
Example usage of interfaces
The Password Handling classes and interfaces are fairly simplistic. The following examples will show how to use them.
Obtaining a KeyStoreUtil
public void init(ComponentContext jbiContext) throws JBIException {
KeyStoreUtil keystoreUtil = null;
if (mContext instanceof com.sun.jbi.component.ComponentContext) {
keystoreUtil = ((com.sun.jbi.component.ComponentContext)mContext).getKeyStoreUtil();
Environment Variables
Within the use of Environment Variables, we need to remember that we are providing create, read, update, and delete functionality. When loading environment variables, you'll be providing mostly read functionality. When storing environment variables, you'll be creating, updating, or deleting environment variables from the data store.
When dealing with password fields, they must be encypted when persisting environment variables. When loading the environment variables from a persistent store, the password fields must be decrypted.
public void persistEnvVariableConfiguration() throws MBeanException {
// Persist the changed configuration
try {
File envVarPersistFileName = new File(mWorkspaceRoot, PERSIST_ENVVAR_CONFIG_FILE_NAME);
OutputStream os = new FileOutputStream(envVarPersistFileName);
for (Iterator iter = mEnvVarMap.keySet().iterator(); iter.hasNext(); ) {
String key = (String);
String[] metadata = (String[]) mEnvVarMap.get(key);
String value = metadata[0];
String type = metadata[1];
if (type.equals("PASSWORD")) {
value = mKeyStoreUtil.encrypt(value);
String prop = (value != null)? key + "=" + value + "{" + type + "}\n" : key + "={" + type + "}\n";
} catch (Exception ex) {
throw new MBeanException(ex, mMessages.getString("RTC_Failed_persist_env_var",
new Object[] {mWorkspaceRoot, ex.getMessage()}));
public Map loadEnvironmentVariableConfig(String workspaceRoot) throws JBIException {
Properties persistedConfig = new Properties();
Map envVarMap = new HashMap();
File envVarPersistFileName = new File(workspaceRoot, PERSIST_ENVVAR_CONFIG_FILE_NAME);
if (!envVarPersistFileName.exists()) {
return envVarMap;
try {
InputStream is = new FileInputStream(envVarPersistFileName);
// load the persisted environment variable configurations in the map
for (Enumeration e = persistedConfig.propertyNames(); e.hasMoreElements(); ) {
String name = (String) e.nextElement();
String metadata = persistedConfig.getProperty(name);
int startIndex = metadata.indexOf("{");
String value = (startIndex == 0)? null : metadata.substring(0, startIndex);
String type = metadata.substring(startIndex + 1, metadata.length() -1);
if (type.equals("PASSWORD")) {
value = mKeyStoreUtil.decrypt(value);
envVarMap.put(name, new String[] {value, type});
} catch (Exception ex) {
throw new JBIException(mMessages.getString("RTC_Failed_loading_env_config", new Object[] {envVarPersistFileName, ex.getMessage()}), ex);
return envVarMap;
Mbean Classes
Mbeans may have attributes that are passwords. In the following example, we assume that Mbeans must be persisted immediately
public String getProxyPassword() throws Exception {
try {
String base64Encoded = mConfig.getProperty(CONFIG_PROXY_PASSWORD);
return mKeyStoreUtil.decrypt(base64Encoded);
} catch (Exception ex) {
throw new Exception(ex);
public void setProxyPassword(String val) throws MBeanException {
String newVal = val;
// Apply the change
String oldVal = null;
try {
oldVal = getProxyPassword();
String base64Encoded = mKeyStoreUtil.encrypt(val);
mConfig.put(CONFIG_PROXY_PASSWORD, base64Encoded);
} catch (Exception ex) {
throw new MBeanException(ex);
// Save the change
// Notify listeners of this change
long seqNo = 0;
String msg = "Attribute changed";
String attrType = String.class.getName();
Notification notif = new AttributeChangeNotification(this, seqNo, System.currentTimeMillis(), msg,
CONFIG_PROXY_PASSWORD, attrType, oldVal, newVal);
User Interface
There are multiple clients that have the ability to view and set passwords. These clients include, but are not limited to, the JBI Manager, Enterprise Manager, the WSDL Editor, and the the CLI. The main underlying principle driving the client interface is that component code should not rely on the client to properly mask passwords. To that end, we have established the following criteria:
1.Make password fields write-only.
Do not allow the clients to "get" the password. This will basically allow no client to inadvertently get the password and expose it to the outside world. For the JBI Manager and Enterprise Manager, we can certainly designate the MBean fields as write-only by providing just a setter method. For the WSDL editor, this is much more difficult since the passwords are stored in a WSDL file that is viewable by all. For CLI, the same problem exists since passwords are often stored in Properties files which are viewable by all.
2.Provide a "proper" password editor.
The only time passwords can be exposed, then, is when the user is setting them. To ensure the integrity of the password, we want to provide the typical password editor that will allow the user to enter the password twice and have the option of having it masked when typing it in.

JSPWiki v2.4.100
« Home Index Changes Prefs
This page (revision-6) was last changed on 27-Jan-10 02:38 AM, -0800 by newacct