IBM Crypto Education Community

IBM Crypto Education Community

IBM Crypto Education Community

Join the IBM Crypto Education community to explore and understand IBM cryptography technology. This community is operated and maintained by the IBM Crypto Development team.

 View Only
  • 1.  Encrypt One field from Table

    Posted Mon July 29, 2024 11:06 AM

    Hello everyone,
    I am a new member of the community and a Master's student researching cryptography in DB2. My initial project involves encrypting and decrypting a field in a table, such as the ID column in a test table. I have generated a key using the KGUP utility, but I am unsure how to utilize this key. Can anyone assist me or provide sample code in REXX or COBOL? I am eager to understand this concept.

    Thank you



    ------------------------------
    Morteza Moradi
    ------------------------------


  • 2.  RE: Encrypt One field from Table

    Posted Mon July 29, 2024 11:08 AM

    What options did you specify in the KGUP control card? With that information, I can try to help.



    ------------------------------
    Eric Rossman
    ------------------------------



  • 3.  RE: Encrypt One field from Table

    Posted Mon July 29, 2024 12:53 PM

    In KGUP Utility using CSFIN dataset, I Maintain (Option 1) ADD Functions with AES Algorithm and Key Type CLRAES labeled as TESTKEY with key values 854F539195C7B7A3. Dataset Values is:

    ADD TYPE(CLRAES),

    KEY(854F539195C7B7A3),

    LAB(TESTKEY)

    After executing JCL Code successfully with reason code 0, I use refresh (Option 4) to update ckds dataset (csf.csfckds). Now, I am unsure of how to apply this key for encrypting a field in a table.



    ------------------------------
    Morteza Moradi
    ------------------------------



  • 4.  RE: Encrypt One field from Table

    Posted Mon July 29, 2024 03:58 PM

    OK, that helps me quite a lot in helping you.

    So, since this is for testing purposes, and you are researching cryptography, I won't go into too much about the security implications of what you are doing unless you want me to.

    As you know, the AES block cipher encrypts 16 bytes at a time. So, to encrypt a column, you will need to pick an encryption mode out of one of three general categories:

    1. Input must be a multiple of 16 bytes (CBC as an example)
    2. Input will be padded (PKCS-PAD as an example)
    3. Input may be any length (OFB as an example)

    Each of the modes has pros and cons.

    Given that you are looking at encrypting a column, you have to decide whether you want to change the column definition from a character string to a binary string and/or change the width of the column.

    ICSF has multiple services with differing features.

    The most powerful service is CSNBSYE which will output binary ciphertext (may require changing the column definition). While this is the most powerful, it is probably not going to be the best option.

    Given that you are looking to do DB2 column encryption, you would probably do well to use format-preserving encryption. I would recommend Field Level Encipher (CSNBFLE and CSNEFLE). It looks complicated, but I will give a sample REXX exec. I'm working on it right now.



    ------------------------------
    Eric Rossman
    ------------------------------



  • 5.  RE: Encrypt One field from Table

    Posted Mon July 29, 2024 05:52 PM
      |   view attached
    My sample has 2 calls to show how to change the tweak value between rows.
     
    I used EPRINT rule which allows for alphanumeric EBCDIC and many symbols.
     
    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
     
    Because of this, k is 18 (18 characters per "block")
     
    I made the context_data have the layout:
     
    '00'X               /* upper 7 bits must be zero */
    '0123456789ABCD'X   /* 7 bytes invariant (set based on this table) */
    '0000000000002A00'X /* first 7 bytes are the row number, last byte is 00 */
     
    The last byte being zero leaves room for each row to have 256*k characters in the encrypted column.


    ------------------------------
    Eric Rossman
    ------------------------------

    Attachment(s)

    txt
    TEMPFLE.txt   10 KB 1 version


  • 6.  RE: Encrypt One field from Table

    Posted Tue July 30, 2024 09:51 AM

      Thank you for you're response. It's help me a lot. I am so confused to how encrypted column and how can I connection to database and use this?  



    ------------------------------
    Morteza Moradi
    ------------------------------



  • 7.  RE: Encrypt One field from Table

    Posted Tue July 30, 2024 09:51 AM

    I wrote this code and merged it with the existing code.

    =======================================================================================================
    /* REXX SCRIPT TO ENCRYPT A DECIMAL(16) COLUMN IN DB2 */                
    /* CONNECT RO DSNREXX*/                                                 
    ADDRESS TSO 'SUBCOM DSNREXX'                                            
    S_RC = RXSUBCOM('ADD','DSNREXX','DSNREXX')                              
    ADDRESS DSNREXX                                                         
    'CONNECT' 'DBAT'                                                        
    SQLTS=,                                                                 
    "SELECT ID FROM TST.TEST"                                              
    "EXECSQL DECLARE S1 CURSOR FOR C1"                                      
    "EXECSQL PREPARE S1 FROM :SQLTS"                                        
    "EXECSQL OPEN C1"                                                       
    "EXECSQL FETCH C1 INTO :FETCHED_DATA"                                   
    /*CONVERT DECIMAL TO CHARACTER FOR ENCRYPTION */                        
    CLEAR_TEXT = LEFT(FETCHED_DATA, 16) /* ENSURE 16-BYTE LENGTH */         
    /* INITIALIZE ENCRYPTION PARAMETERS (SYE) */                            
    /* THESE PARAMETERS SHOULD MATCH THE ONES USED IN YOUR ORIGINAL SCRIPT*/
      AES_DATA_KEY_LABEL = LEFT('TESTKEY',64)                               
      SYE_RC = 'FFFFFFFF'X                                                  
      SYE_RS = 'FFFFFFFF'X                                                  
      EXIT_DATA_LENGTH = '00000000'X                                        
      EXIT_DATA = ''                                                        
      SYE_RULE_ARRAY_COUNT = '00000003'X                                    
      SYE_RULE_ARRAY = 'AES' || 'CLRAES' || 'KEYIDENT' || 'ONLY'            
      SYE_KEY_LENGTH = '00000040'X                                          
      SYE_KEY_IDENTIFIER = AES_DATA_KEY_LABEL                               
      SYE_KEY_PARMS_LENGTH = '00000000'X                                    
     SYE_KEY_PARMS = ''                                                  
     SYE_BLOCK_SIZE = '00000010'X                                        
     SYE_INITIAL_VECTOR_LENGTH = '00000010'X                             
     SYE_INITIAL_VECTOR = '8EBFFE2B973B3121D3858699CB26AAC7'X            
     SYE_CHAIN_DATA_LENGTH = '00000020'X                                 
     SYE_CHAIN_DATA = COPIES('00'X,32)                                   
     SYE_CLEAR_TEXT_LENGTH = D2C(16,4)  /* ENCRYPTING 16 BYTES OF DATA */
     SYE_CLEAR_TEXT = CLEAR_TEXT                                         
     SYE_CIPHER_TEXT_LENGTH = D2C(16,4)                                  
     SYE_CIPHER_TEXT = COPIES('00'X,16)                                  
     SYE_OPTIONAL_DATA_LENGTH = '00000000'X                              
     SYE_OPTIONAL_DATA = ''                                              
    /* CALL ENCRYPTION SERVICE CSNBSYE */                                
     ADDRESS LINKPGM 'CSNBSYE' ,                                         
                     'SYE_RC' ,                                          
                     'SYE_RS' ,                                          
                     'EXIT_DATA_LENGTH' ,                                
                     'EXIT_DATA' ,                                       
                     'SYE_RULE_ARRAY_COUNT' ,                            
                     'SYE_RULE_ARRAY' ,                                  
                     'SYE_KEY_LENGTH' ,                                  
                     'SYE_KEY_IDENTIFIER' ,                              
                     'SYE_KEY_PARMS_LENGTH' ,                            
                     'SYE_KEY_PARMS' ,                                   
                     'SYE_BLOCK_SIZE' ,                                  
                     'SYE_INITIAL_VECTOR_LENGTH' ,                       
                     'SYE_INITIAL_VECTOR' ,                              
                     'SYE_CHAIN_DATA_LENGTH' ,                       
                     'SYE_CHAIN_DATA' ,                              
                     'SYE_CLEAR_TEXT_LENGTH' ,                       
                     'SYE_CLEAR_TEXT' ,                              
                     'SYE_CIPHER_TEXT_LENGTH' ,                      
                     'SYE_CIPHER_TEXT' ,                             
                     'SYE_OPTIONAL_DATA_LENGTH' ,                    
                     'SYE_OPTIONAL_DATA'                             
      IF (SYE_RC \= '00000000'X) THEN                                
       DO                                                            
         SAY 'ENCRYPTION FAILED: RC =' C2X(SYE_RC) 'RS =' C2X(SYE_RS)
       END                                                           
     /* CONVERT ENCRYPTED DATA TO HEXADECIMAL REPRESENTATION */      
     ENCRYPTED_TEXT = C2X(SYE_CIPHER_TEXT)                           
     SAY ENCRYPTED_TEXT   

    BUT I GET RC=0000008 WITH RS =0000007E0



    ------------------------------
    Morteza Moradi
    ------------------------------



  • 8.  RE: Encrypt One field from Table

    Posted Tue July 30, 2024 04:10 PM
    Edited by Eric Rossman Tue July 30, 2024 04:10 PM

    All ICSF rules are 8 characters long, padded on the right with blanks. so, this line

    SYE_RULE_ARRAY = 'AES' || 'CLRAES' || 'KEYIDENT' || 'ONLY'            

    should be

    SYE_RULE_ARRAY = 'AES     ' || 'CLRAES  ' || 'KEYIDENT' || 'ONLY    '

    Also, someone pointed out that you should have a rule array count of 4
    SYE_RULE_ARRAY_COUNT = '00000004'X



    ------------------------------
    Eric Rossman
    ------------------------------