Cipher.doFinal(byte[]) 在解密时返回 0 个字节

Cipher.doFinal(byte[]) is returning 0 bytes on decryption

我在解密过程中遇到 javax.crypto.Cipher 问题。我创建了一个 GitHub repository 来说明我的问题。

基本上,我正在加密一小段数据,"foobar",然后立即尝试解密它。当解密发生时,cipher.doFinal(encryptedBytes),结果是0个解密字节。显然我在这里遗漏了一些东西,但我没有看到它。你看到我的错误了吗?如果有,那是什么?

加密例程如下:

public Optional<EncryptedData> encrypt(String data) {
  Optional<EncryptedData> result = Optional.empty();
  Optional<Cipher> cipherOptional = this.getEncryptCipher();
  if (!cipherOptional.isPresent()) {
    return result;
  }

  Cipher cipher = cipherOptional.get();
  byte[] encryptedBytes = null;
  try {
    encryptedBytes = cipher.doFinal();
  } catch (IllegalBlockSizeException e) {
    log.error("Bad encryption block size: `{}`", e.getMessage());
    log.debug(e.toString());
  } catch (BadPaddingException e) {
    log.error("Bad encryption padding size: `{}`", e.getMessage());
    log.debug(e.toString());
  }

  if (encryptedBytes != null) {
    Base64.Encoder base64 = Base64.getEncoder();
    EncryptedData encryptedData = new EncryptedData(
      cipher.getIV(),
      encryptedBytes
    );

    result = Optional.of(encryptedData);
  }

  return result;
}

以及解密例程:

public Optional<String> decrypt(EncryptedData data) {
  Optional<String> result = Optional.empty();

  Optional<Cipher> cipherOptional = this.getDecryptCipher(data.getIv());
  if (!cipherOptional.isPresent()) {
    return result;
  }

  Cipher cipher = cipherOptional.get();
  byte[] decryptedBytes;
  try {
    decryptedBytes = cipher.doFinal(data.getData());
    result = (decryptedBytes.length > 0) ?
      Optional.of(new String(decryptedBytes)) : result;
  } catch (BadPaddingException e) {
    log.error("Bad encryption padding size: `{}`", e.getMessage());
    log.debug(e.toString());
  } catch (IllegalBlockSizeException e) {
    log.error("Bad encryption block size: `{}`", e.getMessage());
    log.debug(e.toString());
  }

  return result;
}

两者都使用以下例程来初始化密码:

private Optional<Cipher> getCipher(int mode, byte[] iv) {
  // where mode is either 1 -> encrypt or 2 -> decrypt
  Optional<Cipher> result = Optional.empty();

  Cipher cipher = null;
  try {
    cipher = Cipher.getInstance(this.algorithmMode);

    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
    AlgorithmParameters parameters =
      AlgorithmParameters.getInstance(this.algorithm);
    parameters.init(ivParameterSpec);

    cipher.init(mode, this.key, parameters);
    result = Optional.of(cipher);
  } catch (NoSuchAlgorithmException e) {
    log.error("Could not find cipher mode: `{}`", e.getMessage());
    log.debug(e.toString());
  } catch (NoSuchPaddingException e) {
    log.error("Could not find padding type: `{}`", e.getMessage());
    log.debug(e.toString());
  } catch (InvalidKeyException e) {
    log.error("Encryption key is invalid: `{}`", e.getMessage());
    log.debug(e.toString());
  } catch (InvalidParameterSpecException e) {
    log.error("Algorithm parameter spec invalid: `{}`", e.getMessage());
    log.debug(e.toString());
  } catch (InvalidAlgorithmParameterException e) {
    log.error("Algorithm parameters invalid: `{}`", e.getMessage());
    log.debug(e.toString());
  }

  return result;
}

错误最终出现在实际代码中的 line 38

我是不是漏掉了什么,或者您是否提供过实际的加密字节。还是加密0字节?

在加密函数中没有看到任何 cypher.update(byte[])cypher.final(byte[])

您没有呼叫 Cipher.doFinal(byte[])。您正在呼叫 Cipher.doFinal().

尝试做你认为自己正在做的事情。