Key Locator Framework (KLF)
To comply with the Payment Card Industry Data Security Standard (PCI DSS), a Key Locator Framework (KLF) is introduced to allow an encryption key. For example, the merchant key or Payments instance password, can now be stored and retrieved from a configurable location such as from an external, more secure, device. This is accomplished by associating each encryption key with a key provider class.
There are four key providers that are ready for immediate use.
- WCMerchantKeyImpl: stores the merchant key in the instance configuration file
- WCExternalFileMerchantKeyImpl: stores the merchant key in an external file
Key providers for Payments instance password:
- WCPaymentsInstancePasswordImpl: stores the Payments instance password in the Payments instance configuration file
- WCExternalFilePaymentsInstancePasswordImpl: stores the Payments instance password in an external file
If you want to store the encryption key by using a different mechanism, for example, by using a hardware device, you must create a custom key provider class. This class must implement the WCKey interface, and extend from the following abstract class: WCKeyBaseImpl. This abstract class implements some of the common methods on the WCKey interface. The list of encryption keys available to the system is registered in a key configuration file. The default key configuration file is WCKeys.xml. To change the default configuration, a custom key configuration file must be specified in the instance configuration file by using the following attribute: Instance/KeysConfigFile.
An encryption key is defined in the key configuration file as shown here:
<key name="MerchantKey"
providerName="WC"
status="current"
className="com.ibm.commerce.security.keys.MyMerchantKeyImpl"
version="3"
algorithm="AES">
<config name="param1" value="value1"/>
<config name="param2" value="value2"/>
</key>
Where:
- name
- Name of the key. "MerchantKey" refers to the merchant key.
- providerName
- Name of the provider. You can specify your own custom provider name to refer to your customized provider class name.
- status
- Valid values are "current" and "new". At most times, there would
be only a single key for each key name, and that key would have status
"current". In this case, the key would be used for encrypting new
data and decrypting existing data.
While you are running MigrateEncryptedInfo, an extra key with status "new" must be added to the key configuration file.Valid values are "current", "pending" and "new". At most times, there would be only a single key for each key name, and that key would have status "current". In this case, the key would be used for encrypting new data and decrypting existing data.
If you want to change the merchant key while the site is live, in a clustered environment, the new key is introduced in two steps:
- Add the new key to the key configuration file and set its status to "pending". Then, a partial EAR update is called so that the change is picked up. In the clustered environment, as each node picks up the new "pending" key, it can decrypt with the new key, if needed, but never encrypt with it. New encryptions would continue to be done with the highest version "current" key.
- Change the status of the new key from "pending" to "new" in the key configuration file, and then do another partial EAR update. While the change is being propagated, nodes that already picked up the "new" key would use it for any new encryptions. Nodes that have not yet picked up the "new" key would still be able to decrypt any new data by using the "pending" key.
Note: If you are running in a non-clustered environment, the first step of introducing the key with the status of "pending" can be skipped. Once the "new" key is picked up by all the nodes, it is safe to run MigrateEncryptedInfo on the live site. When MigrateEncryptedInfo completes, the "current" key can be removed from the key configuration file and the "new" key can be changed to "current" status. - className
- The Java class that implements your key provider.
version
(Optional) Version of the key. You must specify a version if you plan to run the MigrateEncryptedInfo utility to change the encryption key while the site is live. The MigrateEncryptedInfo utility decrypts data encrypted with the "current" key, and re-encrypts it with the "new" key. When your site is live and the utility is running, WebSphere Commerce must have a way to differentiate data encrypted with the "current" key from data encrypted with the "new" key. For this reason, you must specify a unique version number to associate to each key by using this version parameter. When you encrypt data by using a versioned key, the ActiveProvider encryption provider appends a suffix to the data itself using this convention:
_IBM_n
. For example,_IBM_3
denotes that this data is encrypted with version 3 of the encryption key. The utility appends the data with this suffix in plain text, for example:yXiW3W4iblU=_IBM_3
. Data that was encrypted before versioning was introduced does not have this suffix, and is associated with a key that does not have a version. When you encrypt data at run time, the "new" key provider is used if it is defined. If a "new" key is not defined, then the "current" key with the highest version is used.- config
- (Optional) Parameters that are required by your provider, for example the name of a configuration file.
algorithm
Algorithm for the merchant key. Valid values are "AES" and "3DES". If you are running the MigrateEncryptedInfo command for the first time to migrate encryption from 3DES to AES, set this value to AES. If the algorithm parameter is not specified for the merchant key, the AES_DB parameter is checked in the following file to determine if AES is used:
WC_installdir\xml\product.xml
workspace_dir\WC\xml\config\wc-server.xml
Once all the encryption keys are registered in the key configuration file, the WCKeyRegistry class is used for reading this file and caches all the key providers in memory.
You can use the getKey(strKeyName) and getNewKey(strKeyName) methods of WCKeyRegistry to retrieve the current and new key provider.
WCKey key = WCKeyRegistry.getInstance().getKey(<name of the key>);
String keyValue = key.getValueAsString();
To retrieve the
"new" key with a particular name and provider: WCKey newKey = WCKeyRegistry.getInstance().getNewKey(<name of the key>, <name of the provider>);
String newKeyValue = newKey.getNewValueAsString();
- getKey(strKeyName) Returns the "new" key if it exists, or the "current" key with the highest version
- getCurrentKeys() Returns the current keys
- getNewKey() Returns the new key if it is defined