使用AES / ECB / NoPadding进行加密/解密

时间:2014-02-26 07:10:31

标签: java encryption cryptography

以下是我的加密/解密方法:

private String decrypt_data(String encData) 
                throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
    {
        String key = "bad8deadcafef00d";
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");

        cipher.init(Cipher.DECRYPT_MODE, skeySpec);

        System.out.println("Base64 decoded: "+Base64.decode(encData.getBytes()).length);
        byte[] original = cipher.doFinal(Base64.decode(encData.getBytes()));
        return new String(original).trim();     
    }

    private String encrypt_data(String data) 
                throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
    {
        String key = "bad8deadcafef00d";
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");

        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        System.out.println("Base64 encoded: "+ Base64.encode(data.getBytes()).length);

        byte[] original = cipher.doFinal(Base64.encode(data.getBytes()));
        return new String(original);
    }

所以现在当我尝试加密时,我得到了这个例外:

javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
    at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:854)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:828)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
    at javax.crypto.Cipher.doFinal(Cipher.java:2087)

我在加密和decrpt中尝试使用密码实例AES/ECB/PKCS5Padding。它仅适用于加密而不适用于解密。我想填充是必要的,因为数据大小不是16字节的倍数。 “数据”字节长度打印为152,因此尝试将eight \0字符附加到数据然后加密,它也无法正常工作。

2 个答案:

答案 0 :(得分:4)

我在你的代码中看到了另一个错误:

即使您的加密方法正常工作,您的解密方法也无法正常工作。 实际上,您使用Base64加密,然后使用AES。然后使用Base64和AES解密整个事情。

我几乎可以肯定这两种加密方式都不是可交换的。 (你必须解密AES然后解密Base64)。

考虑这个答案:javax.crypto.IllegalBlockSizeException : Input length must be multiple of 16 when decrypting with padded cipher ,不使用填充(NoPadding arg),你必须使用长度为16的输入字符串。

如果我们用我的评论纠正你的代码,如果我们让密码管理填充,我们得到以下代码,这很好用:

private static String decrypt_data(String encData)
        throws NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    String key = "bad8deadcafef00d";
    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES");

    cipher.init(Cipher.DECRYPT_MODE, skeySpec);

    System.out.println("Base64 decoded: "
            + Base64.decode(encData.getBytes()).length);
    byte[] original = cipher
            .doFinal(Base64.decode(encData.getBytes()));
    return new String(original).trim();
}

private static String encrypt_data(String data)
        throws Exception {
    String key = "bad8deadcafef00d";
    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES");

    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

    System.out.println("Base64 encoded: "
            + Base64.encode(data.getBytes()).length);

    byte[] original = Base64.encode(cipher.doFinal(data.getBytes()));
    return new String(original);
}

答案 1 :(得分:0)

为了解决您的具体问题,我认为您只需要像尝试一样添加8字节填充,而是使用在java字符串(如空格)中有效的内容。