Search code examples
javaencryptionbyteaes

Encryption in Java while Decryption method is known


I try to make encryption and decryption mechanism in Java. I have found some code for decrypting but I don't know how to encrypt. What encryption method will be compatible with decryption method like this:

private byte[] padKey(byte[] key) {
        byte[] paddedKey = new byte[32];
        System.arraycopy(key, 0, paddedKey, 0, key.length);
        return paddedKey;
    }

    private byte[] unpad(byte[] data) {     
        byte[] unpaddedData = new byte[data.length - data[data.length - 1]];
        System.arraycopy(data, 0, unpaddedData, 0, unpaddedData.length);
        return unpaddedData;
    }


public String decrypt(String encodedJoinedData) throws Exception {

        // Base64-decode the joined data
        byte[] joinedData = Base64.decode(encodedJoinedData); 

        // Get IV and encrypted data
        byte[] iv = new byte[16];
        System.arraycopy(joinedData, 0, iv, 0, iv.length);
        byte[] encryptedData = new byte[joinedData.length - iv.length];
        System.arraycopy(joinedData, iv.length, encryptedData, 0, encryptedData.length);

        // Pad key
        byte[] key = padKey("SiadajerSiadajer".getBytes()); 
        Key aesKey = new SecretKeySpec(key, "AES");

        // Specify CBC-mode
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); 
        cipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);

        // Decrypt data
        byte[] decryptedData = cipher.doFinal(encryptedData);

        // Remove custom padding
        byte[] unpaddedData = unpad(decryptedData);         

        return new String(unpaddedData);
    }

Solution

  • If you're looking for an encryption-counterpart to your decrypt-method you have simply to reverse the process in your decrypt-method. The following must be done in the body of the encrypt-method (let plainText be a String-parameter containing the plain text):

    1. Add the custom padding

      // Pad data (custom padding)
      byte[] paddedData = pad(plainText.getBytes(), 16);
      
    2. Encrypt your plain text

      // Pad key 
      byte[] key = padKey("SiadajerSiadajer".getBytes()); 
      Key aesKey = new SecretKeySpec(key, "AES");
      
      // Specify block-cipher (AES), mode (CBC) and padding (PKCS5)
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      
      // Create random IV
      SecureRandom secureRandom = new SecureRandom();
      byte iv[] = new byte[cipher.getBlockSize()];
      secureRandom.nextBytes(iv);
      IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); 
      
      // Encrypt data
      cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec);
      byte[] encryptedData = cipher.doFinal(paddedData);
      
    3. Join IV and encrypted data

      // Join IV and encrypted data
      byte[] joinedData = new byte[iv.length + encryptedData.length];  
      System.arraycopy(iv, 0, joinedData, 0, iv.length);
      System.arraycopy(encryptedData, 0, joinedData, iv.length, encryptedData.length);
      
    4. Base 64-encode the joined data

      // Base64-encode data
      String encodedJoinedData = Base64.encode(joinedData, 0);
      

    Finally, the encodedJoinedData have to be returned.

    Moreover, you have to implement the custom padding. The following method implements a custom PKCS5-Padding and is a possible counterpart to the unpad-method:

    private byte[] pad(byte[] data, int size) {
        byte padLength = (byte)(size - (data.length % size));
        byte[] paddedData = new byte[data.length + padLength];
        System.arraycopy(data, 0, paddedData, 0, data.length);
        for (int i = data.length; i < paddedData.length; i++)
            paddedData[i] = (byte)padLength;
        return paddedData;
    }
    

    Btw, there are a few issues with your decrypt-method (and thus with the encrypt-method):

    • You shouldn't use a hardcoded key, but probably this is only for testing purposes. For creating a secure AES key see e.g. How to create a secure random AES key in Java?.
    • The most obvious flaw is that it's unpadded / padded twice in the decrypt/encrypt-method which doesn't make any sense. Thus, remove either the chosen PKCS5-Padding (i.e. change from AES/CBC/PKCS5Padding to AES/CBC/NoPadding) or the custom padding in both, the decrypt- and encrypt-method (provided that's possible within the scope of your project).