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()
.
尝试做你认为自己正在做的事情。
我在解密过程中遇到 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()
.
尝试做你认为自己正在做的事情。