2013-07-31 36 views
1

是J2ME的新手。目前我被告知要做一個需要AES加密的項目。在Google上進行一些搜索後,我收到了代碼段。代碼沒有加密,而是試圖解密我得到錯誤「InvalidKeyException將」'當,當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 = "ABCDEF"; 

    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(); 
} 
} 

`

+1

請在您的代碼中添加一個'main()'方法,以便我們可以運行它並演示問題。 –

+0

請讓您的經理閱讀以下內容:http://blogs.msdn.com/b/ericlippert/archive/2011/09/27/keep-it-secret-keep-it-safe.aspx還要確保他們明白某人誰在安全和密碼學方面技能不高,將無法使用AES等密碼原語生成安全程序。 – ntoskrnl

+0

您正在使用ECB模式。不要這樣做!這是不安全的。改用CBC或CTR模式。 – rossum

回答

1

你所列出的代碼是壞的一些原因(使用ECB,Cipher不是線程安全的,沒有正確填充填充等),我強烈建議你不要使用它。

我躺在身邊,你應該用它來代替。

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; 
} 
+0

您確定有關SecureRandom ..當我試圖實現上述代碼..我couldnt導入SecureRandom ...我工作j2me – suja

+0

啊,對不起。理想情況下,您應該使用像[BouncyCastle](http://www.bouncycastle.org/java.html)這樣的加密提供程序來提供此功能。用'DigestRandomGenerator rnd = new DigestRandomGenerator(new SHA1Digest())'替換'SecureRandom'。對於測試,您可以改用Java的Random類。不過,我真的鼓勵你在實際部署代碼時使用Bouncy Castle。 – Syon

+0

我得到一個錯誤「invalidkeyexception」做你的想法爲什麼它會來...?我在這裏得到錯誤cipher.init(Cipher.ENCRYPT_MODE,新的SecretKeySpec(key,「AES」),ivSpec); – suja