我遇到了与JCE
相关的问题。
我被要求为解密java.lang.String
实施一个组件。加密的字符串是我们集成的webservice响应的一部分。
Webservice提供商向我们提供了用于解密的二进制文件。
他们还告知了alogirthm:
字符串以64Base编码。所以我们必须在解密前对其进行解码。
解密后,我应该收到一条xml消息
根据这些信息,我研究了如何实现我的组件,这就是我所拥有的:
package org.mycompany.commons;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
//Apache commons IO
import org.apache.commons.io.IOUtils;
/**
* Componente de soporte para codificar y descodificar mensajes
*
* @author opentrends
*
*/
public final class EncryptHelper {
public static final String decrypt(final String encrypted, final String encoding)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException,
BadPaddingException, IOException, InvalidAlgorithmParameterException, NoSuchProviderException {
//Mainly UTF-8
Charset charset = Charset.forName(encoding);
//Decoding binary.
byte[] base64CryptedMessageByteArr = Base64.getDecoder().decode(encrypted);
//Init of descipher
Cipher desCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
AlgorithmParameterSpec ivSpec = new IvParameterSpec(new byte[8]);
desCipher.init(Cipher.DECRYPT_MODE, generateSecretKey(charset),ivSpec);
//Decrypting binary
byte[] byteDecryptedTextByteArr = desCipher.doFinal(base64CryptedMessageByteArr);
String clearText = new String(byteDecryptedTextByteArr, encoding);
return clearText;
}
private final static Key generateSecretKey(Charset charset) throws IOException{
InputStream secretKeyFile = RACEEncrypter.class.getResourceAsStream("/DESedeRACE.key");
InputStreamReader secretKeyReader = new InputStreamReader(secretKeyFile);
byte[] scretKeyByteArr = IOUtils.toByteArray(secretKeyReader);
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey key = factory.generateSecret(new DESedeKeySpec(scretKeyByteArr));
return key;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
执行 decrypt() java会抛出错误:
java.security.InvalidKeyException:密钥长度无效:46个字节
好的,我已经明白 DESede 键不能超过24个字节。 所以我在生成密钥
时尝试过这种方法...
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey key = factory.generateSecret(new DESedeKeySpec(scretKeyByteArr));
return key;
} catch (Exception e) {
e.printStackTrace();
}
return null;
现在Java抛出:
javax.crypto.BadPaddingException:给定最终块未正确填充
我一直在尝试不同的方法,我的下一个尝试过改变算法
Cipher desCipher = Cipher.getInstance("DESede/CBC/NoPadding");
最后我得到一个看起来像这样的二进制文件
解密信息: .B [u85I @米㦬Ë+ S ^
但我希望得到一个XML。
我认为问题很明显。
我已经测试过,使用我们的密钥无法解密Web服务加密的响应。密钥或算法可能会被不知道的原因修改,我们也不知道它