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

时间:2015-01-09 22:16:23

标签: java encryption

我在解密过程中遇到了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

2 个答案:

答案 0 :(得分:1)

我是否遗漏了某些内容,或者您​​是否提供了加密的实际字节数。或者你加密0字节?

在加密功能

中看不到任何cypher.update(byte[])cypher.final(byte[])

答案 1 :(得分:0)

您不是致电 Cipher.doFinal(byte[])。您正在呼叫Cipher.doFinal()

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