Java Cipher解密中的奇怪字符

时间:2016-06-23 10:15:20

标签: java encryption

我的程序有一个奇怪的问题,我想加密一些字符串然后解密它们;我做了一个试验课来测试加密和解密的功能。事情适用于加密,但是当我尝试解密时,有时候,我在字符串中间有奇怪的字符。 这是我的代码:

public class Prova {

public static void main(String[] args){
    String s = "with the lights out is less dangerous here we are now entertain us";
    s = cripta(s);
    System.out.println(s);
    s = decripta(s);
    System.out.println(s);
}

public static String cripta(String s){
    System.out.println("lunghezza stringa:"+s.length());
    byte[] input = s.getBytes();
    byte[] output;
    byte[] keyBytes = hexStringToByteArray("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    byte[] ivBytes = hexStringToByteArray("AAAAAAAAAAAAAAAA");
    String out = "";


    SecretKeySpec key = new SecretKeySpec(keyBytes, "DESede" );
    IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
    try {
        Cipher cp = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cp.init(Cipher.ENCRYPT_MODE, key);
        byte[] criptati = new byte[cp.getOutputSize(input.length)];
        int enc_len = cp.update(input, 0, input.length, criptati, 0);
        enc_len += cp.doFinal(criptati, enc_len);
        out = new String(criptati);
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ShortBufferException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return out;
}

public static String decripta(String s){

    byte[] input = s.getBytes();
    byte[] output;
    byte[] keyBytes = hexStringToByteArray("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    byte[] ivBytes = hexStringToByteArray("AAAAAAAAAAAAAAAA");
    String out = "";

    try {
        SecretKeySpec key = new SecretKeySpec(keyBytes, "DESede");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        Cipher cp = Cipher.getInstance("DESede/ECB/NoPadding");
        cp.init(Cipher.DECRYPT_MODE,  key);
        byte[] decrypt = new byte[cp.getOutputSize(input.length)];

        int dec_len = cp.update(input, 0, input.length, decrypt, 0);
        System.out.println(dec_len);
        dec_len += cp.doFinal(decrypt, dec_len );
        System.out.println(dec_len);
        out = new String(decrypt);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ShortBufferException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return out;
}

private static byte[] hexStringToByteArray(String s) {
    // TODO Auto-generated method stub
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;

}

}

我接收到的输出是“随着灯光熄灭,8岁以下,-xÖÆZŽÏö=æe现在招待我们”

1 个答案:

答案 0 :(得分:0)

问题是加密字节可能包含一些值,这些值在简单转换为String时会导致奇怪的行为。所以你应该像这样使用base64编码:

在encripta中:

wwwroot

in decripta:

out = new String(Base64.getEncoder().encode(criptati));

顺便说一句:为什么使用byte[] input = Base64.getDecoder().decode(s.getBytes()); ?为什么不只是cp.update()那样:

cp.doFinal()

和decripta一样?

修改

删除了所有混乱(TODO-comments,未使用的代码等)的工作示例:

Cipher cp = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cp.init(Cipher.ENCRYPT_MODE, key);
byte[] criptati = cp.doFinal(input);
out = new String(Base64.getEncoder().encode(criptati));