@Override
  public String decrypt(String encrypted) {
    try {
      byte[] decoded = BaseEncoding.base64Url().decode(encrypted);
      Cipher cipher;
      switch (transformation) {
        case AES_CBC_NOPADDING:
          cipher = Cipher.getInstance("AES/CBC/NoPadding");
          cipher.init(Cipher.DECRYPT_MODE, key, generateIv(cipher));
          break;
        case RSA_ECB_PKCS1:
          cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
          cipher.init(Cipher.DECRYPT_MODE, key);
          break;
        default:
          throw new AssertionError("How could this happen...");
      }
      byte[] decrypted = cipher.doFinal(decoded);
      if (decrypted == null || decrypted.length <= cipher.getBlockSize()) {
        throw new RuntimeException("incorrect decrypted text.");
      }
      byte[] data = new byte[decrypted.length - cipher.getBlockSize()];
      System.arraycopy(decrypted, cipher.getBlockSize(), data, 0, data.length);
      return new String(data, UTF_8);
    } catch (BadPaddingException
        | IllegalBlockSizeException
        | InvalidAlgorithmParameterException
        | InvalidKeyException
        | NoSuchAlgorithmException
        | NoSuchPaddingException e) {
      monitor.severe(() -> format("Error decrypting data, length: %s", encrypted.length()), e);
      throw new RuntimeException("Couldn't decrypt data", e);
    }
  }
Provides AES and RSA-based encryption implementations for decryption. See {@link
DecrypterFactory} to create.
libraries/security/src/main/java/org/datatransferproject/security/DecrypterImpl.java