Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Problem encrypting in Triple-DES

843811Mar 22 2005 — edited Mar 23 2005
Here's my scenario.
* I'm receiving a public RSA key from a C application (using openSSL library)
* I create an RSA key from the bytes I'm getting.
* I use RSA key to encrypt a string (known to the C code), and verify that the encryption works
* I generate a payload(Triple-DES) key, encrypt it using the RSA Key, then send the raw bytes to the C code for use
* C code verifies for itself that it can use the tripleDes key created from my bytes to encrypt/decrypt a string
* If everythings succeeded up to this point, I once again encrypt the 'known' data - this time with the triple DES key

Currently when the C code receives my triple-DES encrypted known data, it's the right length, but when it uses the key it created earlier from my bytes to do the decryption, the known data's not there. I may be missing something basic about the key exchange, but I've yet to catch it. I've tried both instantiating the desEde key as a Key and SecretKey. Am I correct that I can be using just one desEde key for everything? Or at least to encrypt the data? If someone could help me figure out why that key's not encrypting correctly - or why the key of C :) is decrypting incorrectly??

(NOTE: All the stuff that I need to do from java has already been done in a C++ client using Crypto5.1, and I'm getting what I can from that code...)


The C code is expecting a 32-byte array with which to construct the TripleDES(DesEde) Key for use. I havent found the exact C++ client code that encodes the 32 byte array (not for lack of looking).

I went with what seemed the standard procedure, constructing the 32 byte[] the Triple-Des key's first 16 bytes. Here's how I coded it:
public byte[] getDesEdeKeyBytes() { 
    KeyGenerator keyGen = KeyGenerator.getInstance("DESede");
    m_desEdeKey = keyGen.generateKey();    // m_desEdeKey is SecretKey
    
    byte[] tripleDesBytes = m_desEdeKey.getEncoded();
    // Grab first 16 bytes of Triple Des key (the last 8 bytes are same as first 8 bytes
    byte[] firstTripleDesBytes = new byte[16]; 
    for(int i=0;i<16;i++){
      firstTripleDesBytes[i]  = tripleDesBytes; }

// Create 32 byte array by taking left/right value from
// the 16 bytes, and creating a byte from each
// e.g. 'E7' becomes 'E' = 14, '7' = 7.
String strFirstTripleDesBytes = printByteArrayAsHex(firstTripleDesBytes);
StringBuffer buffer = new StringBuffer();
byte[] desKeyBytes = new byte[32];
for(int z =0;z<32;z++){
String temp = strFirstTripleDesBytes.substring(z, z + 1);
int myInt = Integer.parseInt(temp, 16 )
desKeyBytes[z] = (byte)myInt;
}
String desKey = buffer.toString();
return desKeyBytes;
}

OUTPUT<<<<<<<
All desKeyBytes = 7af82094eaf8a2a28345b3a29152d38c7af82094eaf8a2a2
first 16 bytes = 7af82094eaf8a2a28345b3a29152d38c
desKeyBytes = 070a0f08020009040e0a0f080a020a02080304050b030a02090105020d03080c
<<<<<OUTPUT>>>>>>>

Here's how I (try to) encrypt the known data (a String - length=61). The EncodedBuffer class is one thats used for writing/reading bytes, and it works plenty of other places in the code, so I'm reasonably certain it works just fine.

  public byte[] desEdeEncrypt(byte[] data) {
    MessageFormatter formatter = new MessageFormatter();
    int paddedBytes = (DES_EDE_BLOCK_SIZE - (data.length%DES_EDE_BLOCK_SIZE));
    // if 0, then pad with 8 bytes TODO:TRC
    int encryptedLen = data.length + (paddedBytes == 0?DES_EDE_BLOCK_SIZE: paddedBytes);
        
    EncodedBuffer origBuffer = new EncodedBuffer(data.length);
    origBuffer.write(data, data.length);
    
    EncodedBuffer encryptedBuffer = new EncodedBuffer(encryptedLen);
    
    try {
      Cipher tripleDes = Cipher.getInstance("DESede/ECB/NoPadding");
      tripleDes.init(Cipher.ENCRYPT_MODE, m_desEdeKey);                // initialize for encrypt mode    
      
      byte[] tempBytes = null;
      byte[] encryptedBytes = null;
        for(int x=0;x<=(data.length - DES_EDE_BLOCK_SIZE);x+=DES_EDE_BLOCK_SIZE){          
          tempBytes = origBuffer.readByteArrayAtOffset(x, DES_EDE_BLOCK_SIZE);
          encryptedBytes = tripleDes.doFinal(tempBytes);
          encryptedBuffer.write(encryptedBytes, DES_EDE_BLOCK_SIZE);          
        }        
        // now we write the last block..
        // possibly some data...
        tempBytes = origBuffer.readByteArray(DES_EDE_BLOCK_SIZE - paddedBytes);
        EncodedBuffer paddingBuffer = new EncodedBuffer(DES_EDE_BLOCK_SIZE);
        paddingBuffer.write(tempBytes, tempBytes.length);
        // plus any padding needed; the last byte will always contain the number of padded bytes
        // if data divides evenly by 8(DES_EDE_BLOCK_SIZE), a block of 8 bytes of value '8' will be added
        byte padChar = (byte)(paddedBytes & 0x0f);
        
        for(int y=0;y<paddedBytes;y++){         
          paddingBuffer.write(padChar);
        }
        encryptedBytes = tripleDes.doFinal(paddingBuffer.getBufferBytes());
        encryptedBuffer.write(encryptedBytes, DES_EDE_BLOCK_SIZE); 
      
    } catch (IoBufferException e2) {
       e2.printStackTrace();
    } 
      
    } catch (NoSuchAlgorithmException e1) {
      e1.printStackTrace();
    } catch (NoSuchPaddingException e1) {
      e1.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
      e.printStackTrace();
    } catch (BadPaddingException e) {
      e.printStackTrace();
    }
    return encryptedBuffer.getBufferBytes();
  } 
  
>>>>>OUTPUT<<<<<<< KNOWN DATA NOT SHOWN (XXXX) FOR OBVIOUS REASONS
paddedBytes = 3
encryptedLen = 64
plain text, x 0= XXXXXXXX
plain text, x 8= XXXXXXXX
plain text, x 16=XXXXXXXX
plain text, x 24=XXXXXXXX
plain text, x 32=XXXXXXXX
plain text, x 40=XXXXXXXX
plain text, x 48=XXXXXXXX
encryptedBuffer.getNumberOfBytesInput = 56
paddingBuffer.getNumberOfBytesInput = 5
padChar = 3
padded buffer = XXXXX
paddingBuffer.getNumberOfBytesInput = 8
encryptedBytes.length = 8
<<<<<OUTPUT>>>>>>>
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Apr 20 2005
Added on Mar 22 2005
11 comments
388 views