In this article, see examples of how to implement the commands needed to integrate data-in-motion security in a U2-based solution. It is not intended to be a very inclusive description on setting up security. It is analogous to a carpenter's guide to the hammer and saw, showing how to cut and nail, but not the exact way to build a house.
Recap of the four worlds of encryption
Encryption is the method that converts readable data into cipher data. While encryption has been used to protect communications for as long as open messages have existed, only organizations and individuals with a need for secrecy have made use of it.
For more information, see "U2 encryption in an open technology world" (developerWorks, April 2006).
A key part of the examples in this article use two U2 Basic subroutines to handle the encrypt and decrypt functions. While the method of utilizing hard-coded programs provides limited security (note you would need to edit, recompile, and recatalog to change), versus a method of dynamically changing the values, we decided to keep it simple and go with the hard-coded example.
The following two code listings (Listings 1 and 2) are used by the remaining U2 program examples. If you intend to follow along with the examples, please copy them into a U2 BP file, then compile and catalog them.
Listing 1. myEncrypt example
SUBROUTINE myEncrypt( indata, outdata )
* Hard coded example of encrypt routine
***
ALG="aes-128-cbc" ; * 128 bit aes-128 algorithm in CBC mode
SALT="" ; * HEX - Initialization Vector
DATALOC=1
KEY="4142434445464748494A4B4C4D4E4F50"; * HEX - Actual Key
KEYLOC=1
ACT=2
KEYACTION=3 ; * KEY_ACTUAL_OPENSSL
IV="4142434445464748"; * SALT Value representing HEX
RLOC=1 ; * Result in String RESULT
STATUS=ENCRYPT(ALG,ACT,indata,DATALOC,KEY,KEYLOC,KEYACTION,SALT,IV,outdata,RLOC)
IF STATUS <> 0 THEN
CRT "Error in Encrypt : "
STOP
END
END
RETURN
|
Listing 2. myDecrypt example
SUBROUTINE myDecrypt( indata, outdata )
*
** Sample program to show encrypt
*
ALG="aes-128-cbc" ; * 128 bit aes-128 algorithm in CBC mode
SALT="" ; * HEX - Initialization Vector
DATALOC=1 ; * Data from string
Key="4142434445464748494A4B4C4D4E4F50"; * HEX - Actual Key
KEYLOC=1
KEYACTION=3 ; * KEY_ACTUAL_OPENSSL
IV="4142434445464748"; * SALT Value representing HEX
RLOC=1 ; * Result in String RESULT
ACT="4" ; * Base64 decode before encryption
*
* Call to DECRYPT function - 0 = good response
*
STATUS=ENCRYPT(ALG,ACT,indata,DATALOC,Key,KEYLOC,KEYACTION,SALT,IV,outdata,RLOC)
IF STATUS <> 0 THEN
CRT "Error in Decrypt : "
STOP
END
RETURN
|
The above programs will be used to encrypt and decrypt the information, which prevents someone from seeing the cleartext information. Yet you must ensure that the data you send encrypted can be decrypted on the other side. Once this is accomplished, you can ensure that you have ample security on your data in motion.
Encrypting your data in motion is simple when you use the standard OpenSSL routines, as covered in "U2 encryption in an open technology world." You are able to encrypt in many different languages. While there are many ways to send data from one system to another, this article focuses on a simple method that uses sockets.
Figure 1. Simple data in motion flow
Figure 1 shows the flow of the simple socket example. The client takes a message, encrypts it, and writes it to the socket. The server reads the message from the socket, decrypts it, and writes back an acknowledgement in clear text to the socket that is then read by the client.
Note that this example exposes the clear text for demonstration purposes. Based on your security needs, you may want to encrypt the information in both directions.
Client/server code examples:
-
U2 to U2: Both the client and the server are written in U2
Basic. See the "U2 client and server" section.
-
C# to U2: The client is written in C#, and the server is
written in U2 Basic. See the
"C# client to U2
server" section.
-
Java to U2: The client is written in Java, and the server is
written in U2 Basic. See the
"Java client to U2
server" section.
Note that while it is possible to show a script example, such a solution would expose information about your encryption. This is due to the fact that scripts are interpreted, and writing them to secure and send your data would expose the components of the security.
The following two code listings (Listings 3 and 4) are used by the remaining U2 program examples. If you intend to follow along with the examples, please copy them into a U2 BP file, then compile and catalog them.
Listing 3. myServer example
*******************************************************************************
*
* Program myServer
*
* Copyright (C) 2008
*
*
*******************************************************************************
*
* Author: mrajkow
* Created on : Aug 15, 2008 10:08:49 AM
* Description: example of socket server
*
*
*****************************************************************************
*
INADDR=""
INNAME=""
CDATLEN = ""
*
**** Specify server name and assign handles to each socket
*
SERVER.IP.ADDRESS="127.0.0.1" ; *myHostName
SOCKET.PORT="8555"
MODE="1" ; * 0=non-blocking, 1=blocking
SERVER_HANDLE="" ; * Server handle
ACCEPTOR_HANDLE="" ; * Acceptor handle
TIMEOUT=200000 ; * milliseconds
*
BACKLOG="2048"
CRT
CRT "Starting Servers"
*
**** Initialize the Server Socket
*
RESULT=initServerSocket(SERVER.IP.ADDRESS,SOCKET.PORT,BACKLOG,SERVER_HANDLE)
CRT "Init server 1 result = ":RESULT
*
*
CRT "Server Accepting connections"
RESULT=acceptConnection(SERVER_HANDLE,MODE,TIMEOUT,INADDR,INNAME,ACCEPTOR_HANDLE)
CRT "Connection ACCEPT Status = ":RESULT
CRT
CLDATA = ""
DONE=""
*
** Read Write loop keeps going until 'Q' is received from client.
*
LOOP UNTIL DONE
*
RESULT=readSocket(ACCEPTOR_HANDLE,CLDATA,CDATLEN,TIMEOUT,MODE,ACTSIZ)
CRT "Read status = ":RESULT
*
CRT " Value of inbuf= ":CLDATA
CONVERT CHAR(13) TO "" IN CLDATA
CONVERT CHAR(10) TO "" IN CLDATA
PRINT "LENGTH = ":LEN(CLDATA)
CRT " Actual size of data = ":ACTSIZ
IF UPCASE(CLDATA[1,1])= "Q" THEN
DONE = 1
CONTINUE
END
clearText = ""
CLDATA=CLDATA:CHAR(10)
CALL myDecrypt(CLDATA, clearText )
SRDATA="Server decrypted client message to : ":clearText:CHAR(10):CHAR(13)
CRT SRDATA
CRT
SDATLEN=""
CDATLEN=""
*
RESULT=writeSocket(ACCEPTOR_HANDLE,SRDATA,TIMEOUT,MODE,SDATLEN)
CRT "Wrote status = ":RESULT
REPEAT
**** Close each of the Sockets
*
RESULT=closeSocket(SERVER_HANDLE)
CRT "result of ?lose server = ":RESULT
RESULT=closeSocket(ACCEPTOR_HANDLE)
CRT "result of close Acceptor = ":RESULT
CRT
END
|
Listing 4. myClient example
*******************************************************************************
*
* Program myClient
*
* Copyright (C) 2008
*
*
*******************************************************************************
*
* Author: mrajkow
* Created on :Aug 15, 2008 10:07:29 AM
* Description:
*
*
*****************************************************************************
*
**** Specify Protocol Logging information
*
RESULT=protocolLogging("myClient.log","ON",10)
CRT "Logging started = ":RESULT
*
reoptVar = "DEBUG,REUSEADDR,KEEPALIVE,DONTROUTE,LINGER,OOBINLINE"
reoptVar := ",SNDBUF,RCVBUF,TYPE,ERROR"
REUSEADDR="1"
CONVERT "," TO @FM IN reoptVar
POP3=@(0,0)
INADDR=""
INNAME=""
*
**** Specify server name and assign handles to each socket
*
SERVER.IP.ADDRESS="localhost"
SOCKET.PORT="8555"
MODE="1" ; * 0=non-blocking, 1=blocking
SOCKETHANDLE1="" ; * Client handle
TIMEOUT=10000 ; * milliseconds
*
BACKLOG="2048"
SERFLAG="-1" ; * Self end = Server
CRT
CRT "Starting Client"
*
**** Open a Client Socket
*
PEERFLAG="0"
CRT "Opening Client"
RESULT=openSocket(SERVER.IP.ADDRESS,SOCKET.PORT,MODE,TIMEOUT, SOCKETHANDLE1)
CRT "Result of client open = ":RESULT
*
**** Get information from the Client Socket
*
RESULT=getSocketInformation(SOCKETHANDLE1, PEERFLAG, SOCKETINFO)
CRT "Client Socket Info"
CRT "-----------"
CRT "Status: ":SOCKETINFO<1,1>
CRT "Host : ":SOCKETINFO<1,2>
CRT "Port : ":SOCKETINFO<1,3>
CRT "Secure: ":SOCKETINFO<1,4>
CRT "Mode : ":SOCKETINFO<1,5>
CRT ""
DONE = 0
*
** Write Read loop continues until the user enters 'Q'
*
LOOP
SDATLEN=""
CDATLEN=""
* Get the data from the user, if 'Q' send it as the last
* message then exit.
CRT "SEND(Type Q or q to Quit): ":;INPUT SRDATA
edata = ""
IF UPCASE(SRDATA) # "Q" THEN
CALL myEncrypt(SRDATA, edata)
END ELSE
edata = "Q"
END
*
edata := CHAR(10):CHAR(13)
RESULT=writeSocket(SOCKETHANDLE1,edata,TIMEOUT,MODE,SDATLEN)
CRT "Wrote status = ":RESULT
UNTIL UPCASE(SRDATA) = "Q"
RESULT=readSocket(SOCKETHANDLE1,CLDATA,CDATLEN,TIMEOUT,MODE,ACTSIZ)
CRT "Read status = ":RESULT
CRT "CLDATA = ":CLDATA
CRT "CDATLEN = ":CDATLEN
REPEAT
RESULT=closeSocket(SOCKETHANDLE1)
CRT "result of close client = ":RESULT
CRT
RESULT=protocolLogging("myClient.log","OFF",10)
CRT "Logging started = ":RESULT
END
|
Listings 3 and 4 use the myEncrypt and myDecrypt routines defined earlier. Watching the output from the myClient and myServer, you can follow along with what is happening:
Listing 5. myClient output
:myClient
Logging started = 0
Starting Client
Opening Client
Result of client open = 0
Client Socket Info
-----------
Status: open
Host : 127.0.0.1
Port : 8555
Secure: non-secure
Mode : blocking
SEND(Type Q or q to Quit): I like U2
Wrote status = 0
Read status = 0
CLDATA = Server decrypted client message to : I like U2
CDATLEN =
SEND(Type Q or q to Quit): q
Wrote status = 0
result of close client = 0
|
Listing 5 shows the output from myClient. The myClient program prompts the user for a message. The user enters "I like U2," and the client encodes it and writes it on the socket. The myServer program reads the information from the socket, decrypts it, and writes back the results. Listing 6 shows the output from the server:
Listing 6. myServer output
:myServer
Logging started = 0
Starting Servers
Init server 1 result = 0
Server Accepting connections
Connection ACCEPT Status = 0
Read status = 0
Value of inbuf= 8c94uaEh1y6dUgBRix6Ejw==
LENGTH = 24
Actual size of data = 27
Server decrypted client message to : I like U2
Wrote status = 0
Read status = 0
Value of inbuf= Q
LENGTH = 1
Actual size of data = 3
result of close server = 0
|
The server program output in Listing 6 shows the encrypted data that was received. It also shows the decrypted information. Please note that this is an example, and, in a production environment, you would not display the decrypted. As another precaution, it is recommended that you consume the information and clear out the variable that contains the information to prevent anyone from seeing it.
The next example again uses the U2 myServer program, but we will talk to it with a C# routine:
Listing 7. tcpipclient.cs example
/* Client Program */
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
public class tcpclient2
{
public static void Main()
{
try
{
TcpClient clientSocket = new TcpClient();
Console.WriteLine("Connecting.....");
clientSocket.Connect("localhost", 8555);
// use the ipaddress as in the server program
Stream stm = clientSocket.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] bToServer;
Console.WriteLine("Connected");
while (true)
{
Console.Write("Enter the string to be transmitted (Type Q or q to Quit):\n");
String ToServer = Console.ReadLine();
if (ToServer.Equals("Q") || ToServer.Equals("q"))
{
Console.Write("Client Disconnected \n");
bToServer = asen.GetBytes(ToServer);
stm.Write(bToServer, 0, bToServer.Length);
clientSocket.Close();
break;
}
// Encrypt Section
// Initialize data string
String b64es = String.Empty;
byte[] fromEncrypt;
byte[] encrypted;
byte[] toEncrypt;
byte[] es;
// Create a new 128 bit key.
byte[] mykey = Encoding.ASCII.GetBytes("ABCDEFGHIJKLMNOP");
// Create a new 64 bit initialization vector
byte[] iv = Encoding.ASCII.GetBytes("ABCDEFGH");
try
{
ASCIIEncoding textConverter = new ASCIIEnc?ding();
// RC2 cryptology
RC2CryptoServiceProvider rc2Crypto = new RC2CryptoServiceProvider();
// set cypher mode
// By default cypher mode CBC is selected ... change CBC to CFB, CTS, ECB,
// OFB as needed.
rc2Crypto.Mode = System.Security.Cryptography.CipherMode.CBC;
// Get an encryptor from key and IV.
ICryptoTransform encryptor = rc2Crypto.CreateEncryptor(mykey, iv);
// Encrypt the data.
MemoryStream rc2msEncrypt = new MemoryStream();
CryptoStream rc2csEncrypt = new CryptoStream(rc2msEncrypt, encryptor,
CryptoStreamMode.Write);
// Convert the data to a byte array.
toEncrypt = textConverter.GetBytes(ToServer);
//Write all data to the crypto stream and flush it.
rc2csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
rc2csEncrypt.FlushFinalBlock();
//Get encrypted array of bytes.
encrypted = rc2msEncrypt.ToArray();
//Convert encrypted to base64
b64es = Convert.ToBase64String(encrypted);
}
catch (Exception e)
{
Console.WriteLine("Error : " + e);
}
//End of Encrypt Section
//Convert String to Byte
bToServer = asen.GetBytes(b64es);
stm.Write(bToServer, 0, bToServer.Length);
byte[] bFromServer = new byte[100];
int rCount = stm.Read(bFromServer, 0, 100);
if (bFromServer.Equals("q") || bFromServer.Equals("Q"))
{
Console.WriteLine("Server Disconnected \n");
clientSocket.Close();
break;
}
else
{
Console.Write("RECEIVED:\n");
for (int i = 0; i < rCount; i++)
//Convert Byte to Char
Console.Write(Convert.ToChar(bFromServer[i]));
Console.Write("\n");
}
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
|
Listings 3 and 4 use the myEncrypt and myDecrypt routines defined earlier. Watching the output from the myClient and myServer, you can follow along with what is happening:
Listing 8. tcpipclient.cs output
Connecting.....
Connected
Enter the string to be transmitted (Type Q or q to Quit):
I like U2
RECEIVED:
Server decrypted client message to : I like U2
Enter the string to be transmitted (Type Q or q to Quit): Q
Server Disconnected
|
Listing 8 shows the output from tcpipclient.cs. It's similar to the myClient program, which prompts the user for a message. The user enters "I like U2," and the client encodes it and writes it on the socket. The myServer program reads the information from the socket, decrypts it, and writes back the results.
Note that since we are using the same U2 server program, we are not duplicating the output.
This last example once again uses the U2 myServer program, but we will talk to it with a Java routine:
Listing 9. tcpClient.java example
import java.io.*;
import java.net.*;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.RC2ParameterSpec;
import sun.misc.BASE64Encoder;
class tcpclient3 {
public static void main(String argv[]) throws Exception {
try {
String FromServer = "";
String ToServer = "";
So?ket clientSocket = new Socket("localhost", 8555);
BufferedReader inFromUser = new BufferedReader(
new InputStreamReader(System.in));
PrintWriter outToServer = new PrintWriter(clientSocket
.getOutputStream(), true);
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
while (true) {
System.out.println("SEND(Type Q or q to Quit):");
ToServer = inFromUser.readLine();
if (ToServer.equals("Q") || ToServer.equals("q")) {
System.out.println("Client Disconnected \n");
outToServer.println(ToServer);
clientSocket.close();
break;
}
else {
// Encrypt Section
// Initialize data string
String b64es = "";
byte[] encrypted;
byte[] toEncrypt;
byte[] fromEncrypt;
byte[] es;
// Create a new 128 bit key.
byte[] mykey = "ABCDEFGHIJKLMNOP".getBytes();
// Create a new 64 bit initialization vector
byte[] iv = "ABCDEFGH".getBytes();
try {
// encrypt
// Constructs a secret key from mykey using RC2
// algorithm
SecretKeySpec key = new SecretKeySpec(mykey, "RC2");
// Constructs a parameter set for RC2 from the given
// effective key size
// (in bits) and IV.
RC2ParameterSpec rc2Spec = new RC2ParameterSpec(128, iv);
// Generates a Cipher object that implements the
// specified transformation.
// *** Very time expensive call ***
// for increase in speed, create object early
Cipher cipher = Cipher.getInstance("RC2/CBC/PKCS5Padding");
// Initializes this cipher with a key and a set of
// algorithm parameters.
// *** time expensive call ***
cipher.init(Cipher.ENCRYPT_MODE, key, rc2Spec, null);
// Get encrypted array of bytes.
//
toEncrypt = ToServer.getBytes();
// Encrypts byte data in a single-part operation, or
// finishes a
// multiple-part operation
encrypted = cipher.doFinal(toEncrypt);
// Base 64 Encode the encrypted string
b64es = new BASE64Encoder().encodeBuffer(encrypted);
///System.out.println("Base64 encrypted output : " + b64es);
} catch (Exception e) {
System.out.println("Error : " + e);
}
// End of Encrypt Section
outToServer.println(b64es);
FromServer = inFromServer.readLine();
if (FromServer.equals("q") || FromServer.equals("Q")) {
System.out.println("Server Disconnected \n");
clientSocket.close();
break;
}
else
{
System.out.println("RECEIVED:" + FromServer);
FromServer = "";
ToServer = "";
}
}
}
} catch (Exception e) {
System.out.println("Error : " + e);
}
}
}
|
Listings 3 and 4 use the myEncrypt and myDecrypt routines defined earlier. Again, watching the output from the myClient and myServer, you can follow along with what is happening:
Listing 10. tcpClient.java output
SEND(Type Q or q to Quit):
I like U2
RECEIVED:Server decrypted client message to : I like U2
SEND(Type Q or q to Quit):
Q
Client Disconnected
|
Listing 10 shows the output from tcpClient.java. It's similar to the myClient program, which prompts the user for a message. The user enters "I like U2," and the client encodes it and writes it on the socket. The myServer program reads the information from the socket, decrypts it,, and writes back the results.
Note that since we are using the same U2 server program, we are not duplicating the output.
In an open technology world, you can never guarantee who the other peer is, and this article covers dealing with secure communication with the most popular technologies. This article is the next step in a series of articles that address securing your data in motion. This article showed that with some simple U2 Basic functions, you can encrypt and decrypt, with the same open source standards as other tools, prior to transmitting. Thus, you can provide good data governance practices and meet regulatory compliances to secure data in motion, as long as the technology you connect to also adheres to the same open source standards.
Learn
-
OpenSSL project Web site: Get more
details about OpenSSL.
-
"
U2 encryption in an open technology world"
(developerWorks, April 2006): Walk through the four worlds of encryption
covering C#, Java, U2 BASIC, and OpenSSL shell scripting and see that
encryption of data produced is interchangeable amongst them.
-
developerWorks U2 product
page:
Get the resources you need to advance your skills in U2.
-
International U2 User
Group:
Find articles and assistance relating to the IBM U2.
- Visit the
IBM U2 product family
page:
Learn more about U2.
- developerWorks Information Management zone:
Learn more about Information Management. Find technical documentation,
how-to articles, education, downloads, product information, and more.
- Stay current with
developerWorks technical events and webcasts.
- Technology bookstore:
Browse for books on these and other technical topics.
Get products and technologies
- Build your next
development project with
IBM trial software,
available for download directly from developerWorks.
Discuss
- Participate in the discussion forum.
- Participate in
developerWorks blogs
and get involved in the developerWorks community.

Michael Rajkowski is a Software Engineer in the IBM U2 Client Support Group. He has over 20 years of experience with MultiValued databases. Michael holds a Bachelor of Science in Computer Science from NYIT and a MBA from Dowling College (Degree Concentration: Total Quality Management).

Nik Kesic works for the IBM U2 Client Support group in Denver, Colorado. Nik's career has spanned consultancy, high-level support, enterprise architecture, and training. He has generated collateral and training material, and has published articles on Web enablement using IBM IDE Tools, sockets, XML, SOAP, SSL, and encryption.
Comments (Undergoing maintenance)





