This is part of the project to set up ICSF so I can create an encrypted dataset on one system, and use it on a different system. This involves setting up keys for encryption, public/private keys and sending stuff between the two systems.
Dataset encryption keys are symmetric and reside in the CKDS.
It took me a while to understand the implications of the fixed and variable format keys, and lots of head scratching when things did not work as expected.
This post is a very simplistic view of the topic – but it should give you enough information to get started with ICSF.
One thing you need to know about (and then quickly forget) is that there are two format of keys.
- Fixed length – an example of this is a DATA key.
- Variable length – an example of this is is a CIPHER key.
I just think of there being two versions of APIs – Version 1 for Data and version 2 for Cipher. Any new project should use variable length keys.
You can use either DATA or CIPHER to encrypt a dataset.
Each type of key has its own APIs, so you cannot use a fixed key in an API designed for variable length keys.
Most ICSF APIs have “rules” which are like passing parameters to a command. This is an array of 8 character strings such as “AES “,”PKCS-1.2”,OP “. This string indicates
- AES – encrypt an AES keyType
- PKCS-1.2 using PKCS
- OP “Operational” for use on this system.
When using the APIs’ to export keys, both ends must have matching configuration
For example with a DATA key any one of the following.
- AES,PKCS-12
- AES,PKCSOAEP
- AES,PKCSOAEP,SHA-512
I think the last set of parameters is the strongest.
For CIPHER, this worked
- AES, PKOAEP2, SHA-256
When programming I found it easier to create some helper routines to reduced the complexity of the APIs. For example I created a ADDKEY routine to specify PKDS|CKDS, the key name, and the buffer contents. As a result I had a high amount of reuse, and my main programs were very compact.
Below I give the API calls for
- Using variable length Cipher keys
- create the skeleton using CSNBKTB2
- create the data key using CSNBKGN2
- export the data key using CSNDSYX
- import the data key (on another system) using CSNDSYI2
- Using fixed length data keys
- create the data key using CSNDSYG
- export the data key using CSNDSYX
- import the data key (on another system) using CSNDSYI
Using variable length Cipher keys
I see the variable length keys as an evolution in key management from the fixed length keys.
For example you can store the name of the key within the key (though I do not know when or how this is used).
Create the skeleton
I built a skeleton using CSNBKTB2. You can optionally pass in
- a key name
- user data
I did not set these (I set the lengths to zero (&zero)).
I passed in the rule
- char 8 rule[4] = “INTERNAL”,”AES “,”CIPHER “, “ANY-MODE”
The ANY-MODE was required for the encryption to work.
Create the cipher key
I then created the key using CSNBKGN2 and passed in
- char8 rule[2] = {“AES “,”OP “};
- keyLength = 256 ; why use a weaker key?
- char8 keyType1 = {“TOKEN “}; This says use the data passed in from the skeleton token.
- char8 keyType2 = {” “};
- The skeleton data
This returns a block of data (the AES Cipher key encrypted with the local key).
I added it to the local keystore using CSNBKRC2.
Export the cipher key
I exported the key using a public certificate with CSNDSYX. I passed
- the name of the public key.
- char8 rule_array[3] = { “AES “,”PKOAEP2 “,”SHA-256 “}
It returns a block of data containing the AES cipher key encrypted with the public key.
I wrote this data to a file (in binary) and sent it to my remote system.
Import the cipher key at the remote system
I read the file into a buffer, and used CSNDSYI2 to decrypt the contents using the private key, and encrypting it with the local key.
I passed
- char8 rule_array[2] ={“AES “,”PKOAEP2 “}
- the name of the private key
- the buffer
it returned a buffer containing the re-encrypted key
I added it to the keystore on the remote system using CSNBKRC2.
__________________________________________________
If you want to use fixed length keys(why do you?)…
Using fixed length data keys
You can create a data key, and export it at a later date, or you can generate it and export it at the same time.
I feel more comfortable about exporting it when it is needed, in case the “old” copy is out of data.
If you export it from the live system you know it is current.
Create the data key
I used use CSNDSYG
with
- a char 64 key name
- char8 rule[3] = {“AES “, “PKCS-1.2″| PKCSOAEP, “OP “}; If you use PKCSOAEP you can specify SHA-512
This creates a data key in the local repository.
I think PKCSOAEP is better than PKCS-1.2 as is is more recent.
You can also get it to create an RSA enciphered version of the key using a public certificate (as part of key creation) This can be written to a file, and the file sent to the remote system. I tend not to use this, but export the key at the time when wanted. This way you can be sure you have the correct key.
Export the data key
Use CSNDSYX with similar parameters as for the create (CSNDSYG) to create an encrypted version of the Data key.
CSNDSYX returns a block of storage with the encrypted key in it. You can write this to a file in binary or create a base64 encoding of it.
Import the data key
Use CSNDSYI with
- The block of encrypted data (which you can read from a file)
- rule = “AES “, “PKCS-1.2″|| “PKCSOAEP”. If you use PKCSOAEP you can specify SHA-512
- The parameters must match the sending end
- The name of the private key in the PKDS to be used to decrypt the data
This returns a block of data which is the data key, encrypted with the local system’s key.
You can then add it to the CKDS using CSNBKRC2