Java 1.8对称DESede加密和解密

时间:2016-09-08 16:30:48

标签: java encryption encryption-symmetric jce secret-key

我遇到了与JCE相关的问题。

上下文

  • SDK:JDK 1.8
  • 操作系统:Ubuntu 14

我被要求为解密java.lang.String实施一个组件。加密的字符串是我们集成的webservice响应的一部分。

Webservice提供商向我们提供了用于解密的二进制文件

  • ProviderDESedeWebservice.key 即可。

他们还告知了alogirthm:

  • DESede / CBC / PKCS5Padding

字符串以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;
        }           
        }       
    }
  • 密钥文件( ProviderDESedeWebservice.key )将位于类路径中。目前我将它放在 resources 文件夹中。

问题

执行 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服务加密的响应。密钥或算法可能会被不知道的原因修改,我们也不知道它

0 个答案:

没有答案