Local security

Local security provides protection for WebSphere MQ Everyplace data or MQeFields objects, including message, MQeMsg, objects. The protected data is returned in a byte array. To apply local security to a data object you must:

  1. Create an attribute with an appropriate authenticator, cryptor, and compressor
  2. Set up an appropriate key (by providing a password or passphrase seed)
  3. Explicitly attach the key to the attribute, the attribute to the data (MQeFields) object, and invoke the dump() function on the data object

The authenticator determines how access to the data is controlled. The cryptor determines the cryptographic strength protecting the data confidentiality. The compressor determines the storage required by the message.

WebSphere MQ Everyplace provides the MQeLocalSecure class to assist with the use of local security. However, it is the responsibility of the local security user to setup an appropriate attribute and provide the password or passphrase key. MQeLocalSecure provides the function to protect the data and to save and restore it from backing storage. If an application chooses to attach an attribute to a message without using MQeLocalSecure, it also needs to save the data after using dump and must retrieve the data before using restore.

Usage scenario

Consider a scenario where mobile agents working on many different customer sites want to ensure that the confidential data of one customer is not accidentally shared with another. Local security features, using different keys, and possibly different cryptographic strengths, provide a simple function for protecting different customer data held on a single machine .

A simple extension of this scenario could be that the protected local data is accessed using a key that is pulled from a secure queue on an WebSphere MQ Everyplace server node. The agents client has to authenticate itself to access the server queue and pull the local key data, but never knows the actual key.

One of the advantages of taking this approach is that an audit trail is easily accumulated for all access to customer specific data.

Secure feature choices

When using MQeLocalSecure, the following attribute choices are available:

Authenticator
Example MQeWTLSCertAuthenticator

Cryptor
One of the symmetric cryptors MQeDESCryptor, MQe3DESCryptor, MQeRC4Cryptor, MQeRC6Cryptor or MQeMARSCryptor

Compressor
MQeLZWCompressor, MQeRleCompressor, or MQeGZIPCompressor

Selection criteria

You should use an authenticator if you need to provide additional controls to prevent access to the local data by unauthorized users. In some ways using an authenticator is unnecessary since providing the key password or passphrase automatically limits access to those who know this secret.

The choice of cryptor is driven by the strength of protection required. The stronger the encryption, the more difficulty an attacker would face when trying to get illegal access to the data. Data protected with symmetric ciphers that use 128 bit keys is acknowledged as more difficult to attack than data protected using ciphers that use shorter keys. However, in addition to cryptographic strength, the selection of a cryptor may also be driven by many other factors. An example is that some financial solutions require the use of triple DES in order to get audit approval.

You should use a compressor if you need to optimize the size of the protected data. However, the effectiveness of the compressor depends on the content of the data. The MQeRleCompressor performs run length encoding . This means that the compressor routines compress or expand repeated bytes. Hence it is effective in compressing and decompressing data with many repeated bytes. MQeLZWCompressor uses the LZW scheme. The simplest form of the LZW algorithm uses a dictionary data structure in which various words (data patterns) are stored against different codes. This compressor is likely to be most effective where the data has a significant number of repeating words (data patterns). The MQeGZIPCompressor uses the same compression algorithm as the gzip command on UNIX. This searches for repeating patterns in the data and replaces subsequent occurrences of a pattern with a reference back to the first occurrence of the pattern.

Usage guide

  1. The following pseudo-code protects an MQeFields object using MQeLocalSecure
    /*SIMPLE PROTECT FRAGMENT */
    			#define BUF_LENGTH		1000		/* assuming this is big enough */
     
    			MQeDESCryptorHndl	desC;
    			MQeAttributeHndl	attr;
    			MQeKeyHndl		localkey;
    			MQeFieldsHndl		myData;
    			MQEBYTE 		protectedData[BUF_LENGTH];
    			MQEINT32		bufLength	=	BUF_LENGTH;
    			MQERETURN		rc;
    			MQeExceptBlock	exceptBlock;
     
    			/*instantiate a DES cryptor */
    			rc = mqeDESCryptor_new(&exceptBlock, &desC);
                 			/*instantiate an Attribute using the DES cryptor */
    			rc = mqeAttribute_new(&exceptBlock, &attr, NULL, 
    											NULL, desC, NULL);
    			/*instantiate a base Key object */
    			rc = mqeKey_new(&exceptBlock, &localKey);
    			/*set the base Key object local key */
    			rc = mqeKey_setLocalKey(localKey, &exceptBlock, 
    												MQeString("my secret key"));
    			/*attach the key to the attribute */
    			rc = mqeAttribute_setKey(attr, &exceptBlock, localkey);
    			/*instantiate a MQeFields object */
                 		 	rc = mqeFields_new(&exceptBlock, &myData);
    			/*attach the attribute to the data object */
    			mqeFields_setAttribute(myData, &exceptBlock, attr);
    			/*add some test data */
    			rc = mqeFields_putAscii(myData, &exceptBlock, MQeString("testdata"), 
                                    MQeString("0123456789abcdef...."));
    			/*encode the data */
    			rc = mqeFields_dump(myData, &exceptBlock, protectedData, 
    													&bufLength, MQE_FALSE);
     
    			/* SIMPLE UNPROTECT FRAGMENT                                  */
    			#define BUF_LENGTH		1000		/* assuming this is big enough */
     
    			MQeDESCryptorHndl	desC2;
    			MQeAttributeHndl	attr2;
    			MQeLocalSecureHndl	ls2;
    			MQEBYTE 		outBuf[BUF_LENGTH];
    			MQEINT32		bufLength	=	BUF_LENGTH;
    			MQERETURN		rc;
    			MQeExceptBlock	exceptBlock;
     
    			/* instantiate a DES cryptor                                  */
    			rc = mqeDESCryptor_new(&exceptBlock, &desC2);
    			/* instantiate an attribute using the DES cryptor             */
      		             rc = mqeAttribute_new(&exceptBlock, 
    														&attr2, NULL, NULL, des2C, NULL);
    			/* instantiate a (a helper) LocalSecure object                */
    		               rc = mqeLocalSecure_new(&exceptBlock, &ls2);
    			/* open LocalSecure obj identifying target file and directory */
    			rc = mqeString_newChar8(&exceptBlock, &fileDir, ".\\");
    			rc = mqeLocalSecure_open(ls2,  &exceptBlock, MQeString(".\\"), 
                                      MQeString("TestSecureData.txt"));
     
    			/* use LocalSecure read to restore from target and decode data */
    			rc = mqeLocalSecure_read(ls2, &exceptBlock, outBuf, &bufLength, 
                                     attr2, MQeString("my secret key"));
     
    
  2. The following pseudo-code protects an MQeFields locally without using MQeLocalSecure.
    /*SIMPLE PROTECT FRAGMENT */
    			#define BUF_LENGTH		1000		/* assuming this is big enough */
     
    			MQeDESCryptorHndl	desC;
    			MQeAttributeHndl	attr;
    			MQeKeyHndl		localkey;
    			MQeFieldsHndl		myData;
    			MQEBYTE 		protectedData[BUF_LENGTH];
    			MQEINT32		bufLength	=	BUF_LENGTH;
    			MQERETURN		rc;
    			MQeExceptBlock	exceptBlock;
     
    			/*create a DES cryptor */
    			rc = mqeDESCryptor_new(&exceptBlock, &desC);
                 			/*create an Attribute using the DES cryptor */
    			rc = mqeAttribute_new(&exceptBlock,&attr, NULL, NULL, desC, NULL);
    			/*create a base Key object */
    			rc = mqeKey_new(&exceptBlock, &localKey);
    			/*set the base Key object local key */
    			rc = mqeKey_setLocalKey(localKey, &exceptBlock, 
    											 MQeString("my secret key"));
    			/*attach the key to the attribute */
    			rc = mqeAttribute_setKey(attr, &exceptBlock, localkey);
    			/*create a MQeFields object */
                 			rc = mqeFields_new(&exceptBlock, &myData);
    			/*attach the attribute to the data object */
    			mqeFields_setAttribute(myData, &exceptBlock, attr);
    			/*add some test data */
    			rc = mqeFields_putAscii(myData, &exceptBlock, 
                                    MQeString("testdata"), 
    											 MQeString("0123456789abcdef...."));
    			/*encode the data */
    			rc = mqeFields_dump(myData, &exceptBlock, protectedData, 
    										&bufLength, MQE_FALSE);
     
    			/* SIMPLE UNPROTECT FRAGMENT                                  */
    			#define BUF_LENGTH		1000		/* assuming this is big enough */
     
    			MQeDESCryptorHndl	desC2;
    			MQeAttributeHndl	attr2;
    			MQeKeyHndl		localKey2;
    			MQeFieldsHndl		myData2;
    			MQEBYTE 		protectedData[BUF_LENGTH];
    			MQEINT32		bufLength	=	BUF_LENGTH;
    			MQERETURN		rc;
    			MQeExceptBlock	exceptBlock;
     
    			/* read protected data into protectedData and set 
    				bufLength to the data length */
    			...
    			/* create a DES cryptor  */
    			rc = mqeDESCryptor_new(&exceptBlock, &desC2);
    			/*create an attribute using the DES cryptor             */
                  			rc = mqeAttribute_new(&exceptBlock, &attr2, 
                                                  NULL, NULL, des2C, NULL);
    			/* create a (a helper) LocalSecure object                */
                  			rc = mqeKey_new(&exceptBlock, &localKey);
    			/*set the base Key object local key */
    			rc = mqeKey_setLocalKey(localKey2, &exceptBlock, 
    											 MQeString("my secret key"));
    		        	/*attach the key to the attribute */
    			mqeAttribute_setKey(attr2, &exceptBlock, localkey2);
    			 /*create a new data object */
    			rc = mqeFields_new(&exceptBlock, &myData);
    			/*attach the attribute to the data object */
    			mqeFields_setAttribute(myData2, &exceptBlock, attr2);
    			/*decode the data */
    			mqeFields_restore(myData2, &exceptBlock, protectedData, 
    									 bufLength, MQE_FALSE);
     
    


© IBM Corporation 2002. All Rights Reserved