InvalidCiphertextException received when trying to decrypt an encoded string using AWS KMS

32 views Asked by At

I'm working on a java program to encrypt a string using AWS KMS key and AES_256 algorithm. I have used customer managed key from AWS KMS. When I encrypt the data, I'm getting an encrypted text. But when I tries to decrypt that encrypted text, I'm getting InvalidCiphertextException exception. Below is my code

`public String encrypt(String plaintext) throws Exception {

   try {
      // Generate AES key
      KeyGenerator keyGen = KeyGenerator.getInstance("AES");
      keyGen.init(256);
      SecretKey secretKey = keyGen.generateKey();

      // Encrypt AES key with AWS KMS
      EncryptRequest encryptKeyRequest = new EncryptRequest()
        .withKeyId(keyId)
        .withPlaintext(ByteBuffer.wrap(secretKey.getEncoded()));
      EncryptResult encryptKeyResult = awsClient.encrypt(encryptKeyRequest);
      byte[] encryptedKeyBytes = encryptKeyResult.getCiphertextBlob().array();

      // Encrypt plaintext with AES
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secretKey.getEncoded(), "AES"));
      byte[] paddedPlaintext = addPadding(plaintext.getBytes(), cipher.getBlockSize());
      byte[] encryptedBytes = cipher.doFinal(paddedPlaintext);

      // Combine encrypted AES key and encrypted data for storage
      byte[] combinedBytes = ArrayUtils.addAll(encryptedKeyBytes, encryptedBytes);

      return Base64.encodeAsString(combinedBytes);
    } catch (Exception e) {
      System.err.println("Error encrypting the text: " + e.getMessage());
      return null;
    }
  }

  public String decrypt(String encryptedText) throws Exception {

    try {
      // Decode combined encrypted bytes
      byte[] combinedBytes = Base64.decode(encryptedText);

      // Extract encrypted AES key and encrypted data
      int keySize = 32; // AES-256 key size in bytes
      byte[] encryptedKeyBytes = new byte[keySize];
      byte[] encryptedBytes = new byte[combinedBytes.length - keySize];
      System.arraycopy(combinedBytes, 0, encryptedKeyBytes, 0, keySize-1);
      System.arraycopy(combinedBytes, keySize, encryptedBytes, 0, encryptedBytes.length);

      // Decrypt AES key with AWS KMS
      DecryptRequest decryptKeyRequest = new DecryptRequest().withCiphertextBlob(ByteBuffer.wrap(encryptedKeyBytes));
      DecryptResult decryptKeyResult = awsClient.decrypt(decryptKeyRequest);
      byte[] decryptedKeyBytes = decryptKeyResult.getPlaintext().array();

      // Decrypt data with AES
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptedKeyBytes, "AES"));
      byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

      // Remove padding
      byte[] unpaddedBytes = removePadding(decryptedBytes);

      return new String(unpaddedBytes);
    } catch (Exception e) {
      System.err.println("Error decrypting the text: " + e.getMessage());
      return null;
    }
  }

  private static byte[] addPadding(byte[] data, int blockSize) {
    int paddingSize = blockSize - (data.length % blockSize);
    byte paddingByte = (byte) paddingSize;
    byte[] paddedData = new byte[data.length + paddingSize];
    System.arraycopy(data, 0, paddedData, 0, data.length);
    for (int i = data.length; i < paddedData.length; i++) {
      paddedData[i] = paddingByte;
    }
    return paddedData;
  }

  private static byte[] removePadding(byte[] data) {
    int paddingSize = data[data.length - 1];
    return ArrayUtils.subarray(data, 0, data.length - paddingSize);
  }
`

I wish to know what went wrong with this implementation and is there any alternative way to handle this requirement other than this

0

There are 0 answers