Encryption AES算法中的Invalidkeyexception

Encryption AES算法中的Invalidkeyexception,encryption,java-me,aes,Encryption,Java Me,Aes,我是J2ME的新手。目前,我被告知要做一个需要AES加密的项目。我在谷歌上搜索了一下,得到了一段代码片段。该代码确实加密,但在尝试解密时出现错误“Invalidkeyexception” 代码是 package com.cellapp.voda.vault.others; import java.security.*; import java.security.spec.InvalidKeySpecException; import javax.crypto.*; import javax.c

我是J2ME的新手。目前,我被告知要做一个需要AES加密的项目。我在谷歌上搜索了一下,得到了一段代码片段。该代码确实加密,但在尝试解密时出现错误“Invalidkeyexception”

代码是

package com.cellapp.voda.vault.others;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;


public class Codec {

    private Cipher cipher = null;
    private boolean operative = true;

    public Codec() {

        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        } catch (NoSuchAlgorithmException e) {
            // This should not happen since we know the target platform
            // but we set the operative flag to false just in case
            operative = false;
        } catch (NoSuchPaddingException e) {
            // This should not happen since we know the target platform
            // but we set the operative flag to false just in case
            operative = false;
        }
    }


    public void encrypt(byte[] keyBits, byte[] plaintext)
            throws InvalidKeySpecException, InvalidKeyException,
            IllegalStateException, ShortBufferException,
            IllegalBlockSizeException, BadPaddingException,
            InvalidAlgorithmParameterException {
            byte[] cipherText = null;
        if (operative) {
           try{
                // Initialize the key from  the password
            Key key = new SecretKeySpec(keyBits, 0, keyBits.length, "AES");
            // add 2 bytes to encode the length of the plaintext
            // as a short value
            byte[] plaintextAndLength = new byte[plaintext.length + 2];
            plaintextAndLength[0] = (byte) (0xff & (plaintext.length >> 8));
            plaintextAndLength[1] = (byte) (0xff & plaintext.length);
            // build the new plaintext
            System.arraycopy(plaintext,
                    0,
                    plaintextAndLength,
                    2,
                    plaintext.length);

            // calculate the size of the ciperthext considering
            // the padding
            int blocksize = 16;
            int ciphertextLength = 0;
            int remainder = plaintextAndLength.length % blocksize;
            if (remainder == 0) {
                ciphertextLength = plaintextAndLength.length;
            } else {
                ciphertextLength = plaintextAndLength.length - remainder
                        + blocksize;
            }
            cipherText = new byte[ciphertextLength];

            // reinitialize the cipher in encryption mode with the given key
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // do the encryption
            cipher.doFinal(plaintextAndLength,
                    0,
                    plaintextAndLength.length,
                    cipherText,
                    0);
           }
           catch(Exception e)
           {
               System.out.println("TT " + cipherText);
           }


        } else {
            throw new IllegalStateException("Codec not initialized");
        }
    }

    public void decrypt(byte[] keyBits, byte[] cipherText)
            throws InvalidKeySpecException, InvalidKeyException,
            IllegalStateException, ShortBufferException,
            IllegalBlockSizeException, BadPaddingException,
            InvalidAlgorithmParameterException {
        if (operative) {
            // create a key from the keyBits
            Key key = new SecretKeySpec(keyBits, 0, keyBits.length, "AES");

            // Initialize the cipher in decrypt mode
            cipher.init(Cipher.DECRYPT_MODE, key);

            byte[] decrypted = new byte[cipherText.length];
            // Decrypt the cipher text
            cipher.doFinal(cipherText, 0, cipherText.length, decrypted, 0);
            // Calculate the length of the plaintext
            int plainTextLength = (decrypted[0] << 8)
                    | (decrypted[1] & 0xff);
            byte[] finalText = new byte[plainTextLength];
            // Decode the final text
            System.arraycopy(decrypted, 2, finalText, 0, plainTextLength);

            System.out.println("fina;  text " + finalText);
        } else {
            throw new IllegalStateException("Codec not initialized");
        }
    }

    // Displays ecrypted data in hex
    public String byteToHex(byte[] data) {
        StringBuffer hexString = new StringBuffer();
        String hexCodes = "0123456789ABCDEF";

        for (int i = 0; i < data.length; i++) {
            hexString.append(hexCodes.charAt((data[i] >> 4) & 0x0f));
            hexString.append(hexCodes.charAt(data[i] & 0x0f));
            if (i < data.length - 1) {
                hexString.append(":");
            }
            if (((i + 1) % 8) == 0) {
                hexString.append("\n");
            }
        }
        return hexString.toString();
    }
}
package com.cellapp.voda.vault.others;
导入java.security.*;
导入java.security.spec.InvalidKeySpecException;
导入javax.crypto.*;
导入javax.crypto.spec.SecretKeySpec;
公共类编解码器{
私有密码=null;
私有布尔运算=真;
公共编解码器(){
试一试{
cipher=cipher.getInstance(“AES/ECB/PKCS5Padding”);
}捕获(无算法异常){
//这不应该发生,因为我们知道目标平台
//但为了以防万一,我们把操作标志设为false
有效=错误;
}捕获(无此填充例外){
//这不应该发生,因为我们知道目标平台
//但为了以防万一,我们把操作标志设为false
有效=错误;
}
}
公共无效加密(字节[]密钥位,字节[]明文)
抛出InvalidKeySpecException,InvalidKeyException,
IllegalStateException,ShortBufferException,
IllegalBlockSizeException,BadPaddingException,
无效算法参数异常{
字节[]密文=空;
如果(有效){
试一试{
//从密码初始化密钥
Key Key=新的SecretKeySpec(keyBits,0,keyBits.length,“AES”);
//添加2个字节以编码明文的长度
//作为短期价值
字节[]明文和长度=新字节[plaintext.length+2];
明文和长度[0]=(字节)(0xff&(明文.length>>8));
明文和长度[1]=(字节)(0xff和明文.length);
//构建新的明文
System.arraycopy(纯文本,
0,
明文和长度,
2.
明文。长度);
//计算ciperthext的大小,考虑
//填充物
int blocksize=16;
int-ciphertextLength=0;
整数余数=明文和长度.length%块大小;
如果(余数==0){
ciphertextLength=明文和长度.length;
}否则{
ciphertextLength=plaintextAndLength.length-余数
+块大小;
}
密文=新字节[密文长度];
//使用给定密钥在加密模式下重新初始化密码
cipher.init(cipher.ENCRYPT_模式,密钥);
//加密吗
cipher.doFinal(明文和长度,
0,
plaintextAndLength.length,
密文,
0);
}
捕获(例外e)
{
System.out.println(“TT”+密文);
}
}否则{
抛出新的IllegalStateException(“编解码器未初始化”);
}
}
公共无效解密(字节[]密钥位,字节[]密文)
抛出InvalidKeySpecException,InvalidKeyException,
IllegalStateException,ShortBufferException,
IllegalBlockSizeException,BadPaddingException,
无效算法参数异常{
如果(有效){
//从密钥位创建密钥
Key Key=新的SecretKeySpec(keyBits,0,keyBits.length,“AES”);
//在解密模式下初始化密码
cipher.init(cipher.DECRYPT_模式,密钥);
byte[]decrypted=新字节[cipherText.length];
//解密密文
cipher.doFinal(密文,0,密文长度,解密,0);
//计算明文的长度
int plainTextLength=(解密的[0]>4)&0x0f);
append(hexCodes.charAt(数据[i]&0x0f));
如果(i
您列出的代码不好,原因有很多(使用ECB、密码不是线程安全的、填充不正确等等),我强烈建议您不要使用它

我把它放在那里了,你应该用它来代替

public static void main(String[] args) throws DecoderException, InvalidKeyException,
        NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException {
    //Hex encoding/decoding done with Apache Codec library.
    //key MUST BE 16, 24 or 32 random bytes.
    //Do not reuse this key! Create your own.
    byte[] key = Hex.decodeHex("a3134dfd51c30f6e25343d861320668e".toCharArray());
    String text = "This is some test text.";

    byte[] encrypted = encrypt(key, text.getBytes());
    byte[] decrypted = decrypt(key, encrypted);

    System.out.println("Text: " + text);
    System.out.println("Encrypted: " + Hex.encodeHexString(encrypted));
    System.out.println("Decrypted: " + new String(decrypted));
}

public static byte[] encrypt(byte[] key, byte[] unencrypted) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException{
    //Create an initialization vector
    //SecureRandom is not available on J2ME, so we use Bouncy Castle's DigestRandomGenerator instead.
    DigestRandomGenerator rnd = new DigestRandomGenerator(new SHA1Digest());
    //SecureRandom rnd = new SecureRandom();
    byte[] iv = new byte[16];
    rnd.nextBytes(iv);
    IvParameterSpec ivSpec = new IvParameterSpec(iv);

    //Set up the cipher and encrypt
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), ivSpec);
    byte[] encrypted = cipher.doFinal(unencrypted);

    //Append the encrypted text to the IV
    byte[] output = new byte[iv.length + encrypted.length];
    System.arraycopy(iv, 0, output, 0, iv.length);
    System.arraycopy(encrypted, 0, output, iv.length, encrypted.length);
    return output;
}

public static byte[] decrypt(byte[] key, byte[] encrypted) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException{
    //Separate the IV and encrypted text
    byte[] iv = new byte[16];
    byte[] encryptedText = new byte[encrypted.length - iv.length];
    System.arraycopy(encrypted, 0, iv, 0, iv.length);
    System.arraycopy(encrypted, iv.length, encryptedText, 0, encryptedText.length);

    //Decrypt the encrypted text
    IvParameterSpec ivSpec = new IvParameterSpec(iv);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), ivSpec);
    byte[] decrypted = cipher.doFinal(encryptedText);

    return decrypted;
}

您列出的代码不好有很多原因(使用ECB、密码不是线程安全的、填充不正确等等),我强烈建议您不要使用它

我把它放在那里了,你应该用它来代替

public static void main(String[] args) throws DecoderException, InvalidKeyException,
        NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException {
    //Hex encoding/decoding done with Apache Codec library.
    //key MUST BE 16, 24 or 32 random bytes.
    //Do not reuse this key! Create your own.
    byte[] key = Hex.decodeHex("a3134dfd51c30f6e25343d861320668e".toCharArray());
    String text = "This is some test text.";

    byte[] encrypted = encrypt(key, text.getBytes());
    byte[] decrypted = decrypt(key, encrypted);

    System.out.println("Text: " + text);
    System.out.println("Encrypted: " + Hex.encodeHexString(encrypted));
    System.out.println("Decrypted: " + new String(decrypted));
}

public static byte[] encrypt(byte[] key, byte[] unencrypted) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException{
    //Create an initialization vector
    //SecureRandom is not available on J2ME, so we use Bouncy Castle's DigestRandomGenerator instead.
    DigestRandomGenerator rnd = new DigestRandomGenerator(new SHA1Digest());
    //SecureRandom rnd = new SecureRandom();
    byte[] iv = new byte[16];
    rnd.nextBytes(iv);
    IvParameterSpec ivSpec = new IvParameterSpec(iv);

    //Set up the cipher and encrypt
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), ivSpec);
    byte[] encrypted = cipher.doFinal(unencrypted);

    //Append the encrypted text to the IV
    byte[] output = new byte[iv.length + encrypted.length];
    System.arraycopy(iv, 0, output, 0, iv.length);
    System.arraycopy(encrypted, 0, output, iv.length, encrypted.length);
    return output;
}

public static byte[] decrypt(byte[] key, byte[] encrypted) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException{
    //Separate the IV and encrypted text
    byte[] iv = new byte[16];
    byte[] encryptedText = new byte[encrypted.length - iv.length];
    System.arraycopy(encrypted, 0, iv, 0, iv.length);
    System.arraycopy(encrypted, iv.length, encryptedText, 0, encryptedText.length);

    //Decrypt the encrypted text
    IvParameterSpec ivSpec = new IvParameterSpec(iv);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), ivSpec);
    byte[] decrypted = cipher.doFinal(encryptedText);

    return decrypted;
}

请添加一个
main()
方法,以便我们可以运行代码并演示问题。请让您的经理阅读以下内容:同时确保他们了解,不精通安全和加密技术的人将无法使用加密原语(如AES)生成安全程序。您使用的是ECB模式。不要那样做!这是不安全的。改为使用CBC或CTR模式。rossum好的,我将与THT进行检查,请添加一个
main()
方法,以便我们可以运行代码并演示问题。请让您的经理阅读以下内容:同时确保他们了解,不精通安全和加密技术的人将无法使用加密原语(如AES)生成安全程序。您使用的是ECB模式。不要那样做!这是不安全的。使用CBC或CTR模式代替。rossum好的,我会与thtr确认SecureRandom。。当我尝试实现上述代码时。。我无法导入。。。我正在研究j2meAh,对此很抱歉。理想情况下,您应该使用加密提供程序来提供此功能。更换
SecureRandom