简体   繁体   English

AES加密给定最终块未正确填充

[英]AES Encryption Given Final Block Not Properly Padded

I'm trying to create a class that will allow me to encrypt and decrypt strings using the AES algorithm. 我正在尝试创建一个允许我使用AES算法加密和解密字符串的类。 I'm using the exception from http://aesencryption.net/#Java-aes-encryption-example but have modified the code to suit my needs. 我正在使用http://aesencryption.net/#Java-aes-encryption-example中的例外,但修改了代码以满足我的需要。

This is my Main.java: 这是我的Main.java:

public class Main {

    public static void main(String[] args) {

        AES256 aes = new AES256();

        aes.setKey("Secret Key");

        String enc = "";
        enc = aes.encrypt("qwertyuiopasdfgh");

        System.out.println(enc);
        System.out.println(aes.decrypt(enc));


    }

}

And this is my AES256.java: 这是我的AES256.java:

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class AES256 {

    private SecretKeySpec secretKey;
    private byte[] key;

    public void setKey(String key) {    
        MessageDigest sha = null;
        try {
            this.key = key.getBytes("UTF-8");
            sha = MessageDigest.getInstance("SHA-1");
            this.key = sha.digest(this.key);
            this.key = Arrays.copyOf(this.key, 16);
            secretKey = new SecretKeySpec(this.key, "AES");
        } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    public String getSecretKey() {
        return secretKey.toString();
    }

    public String getKey() {
        return new String(key);
    }

    public String encrypt(String string) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            return Base64.getMimeEncoder().encodeToString(string.getBytes());
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String decrypt(String string) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            return new String(cipher.doFinal(Base64.getMimeDecoder().decode(string.getBytes())));
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

}

This is the error that is being thrown: 这是抛出的错误:

javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
    at javax.crypto.Cipher.doFinal(Cipher.java:2121)
    at AES256.decrypt(AES256.java:55)
    at Main.main(Main.java:13)

Does anybody know what is causing this error? 有人知道是什么导致了这个错误吗?

You return the original string in its base64-encoded form: 您以base64编码的形式返回原始字符串:

return Base64.getMimeEncoder().encodeToString(string.getBytes());

You'd want to use the cipher in there as well: 你也想在那里使用密码:

return Base64.getMimeEncoder().encodeToString(cipher.doFinal(string.getBytes()));

Independent of that, when depolying own crypto please be aware of the impacts of cipher modes, padding, etc. For example the ECB mode you're using will produce the same ciphertext from the same plaintext, eg the ciphertext might lead hints about the original text, as in the famous encrypted tux image: 独立于此,当我们自己的加密请求时,请注意密码模式,填充等的影响。例如,您使用的ECB模式将从相同的明文生成相同的密文,例如密文可能会提示有关原始密码的提示文本,如着名的加密tux图像:

在此输入图像描述

Image Copyright: All uses are permitted provided that Larry Ewing, the owner of the original image, who requires that you mention him, his email address, lewing@isc.tamu.edu, and The GIMP, according to http://www.isc.tamu.edu/~lewing/linux/ . 图片版权:如果原始图片的所有者Larry Ewing要求您提及他,他的电子邮件地址,lewing @ ob.tamu.edu和GIMP,根据http:// www。 isc.tamu.edu/~lewing/linux/

For more details on that, see Wikipedia's article about block cipher modes . 有关详细信息,请参阅Wikipedia关于分组密码模式的文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM