2011-03-05 81 views
0

我相信這是從的片段androidsnippets.org - 爲什麼這不是在Android上的功能2.3?如何解決它?密碼墊塊損壞薑餅

錯誤

03-05 23:19:17.479: WARN/System.err(3598): javax.crypto.BadPaddingException: pad block corrupted 
03-05 23:19:17.518: WARN/System.err(3598):  at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:715) 
03-05 23:19:17.518: WARN/System.err(3598):  at javax.crypto.Cipher.doFinal(Cipher.java:1090) 

我發現關於這個主題的幾個答案,但我無法找到一個體面的方式如何解決這一點,添加NoPadding參數或不同算法或.. ?

public static String code(String stringToCode) { 
    try { 
     stringToCode = encrypt("somekey",stringToCode); 
    } catch (Exception e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    return stringToCode; 
} 

public static String decode(String stringToDecode) { 
    try { 
     stringToDecode = decrypt("somekey",stringToDecode); 
    } catch (Exception e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    return stringToDecode; 
} 

public static String encrypt(String seed, String cleartext) throws Exception { 
    byte[] rawKey = getRawKey(seed.getBytes()); 
    byte[] result = encrypt(rawKey, cleartext.getBytes()); 
    return toHex(result); 
} 

public static String decrypt(String seed, String encrypted) throws Exception { 
    byte[] rawKey = getRawKey(seed.getBytes()); 
    byte[] enc = toByte(encrypted); 
    byte[] result = decrypt(rawKey, enc); 
    return new String(result); 
} 

private static byte[] getRawKey(byte[] seed) throws Exception { 
    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
    sr.setSeed(seed); 
    kgen.init(128, sr); // 192 and 256 bits may not be available 
    SecretKey skey = kgen.generateKey(); 
    byte[] raw = skey.getEncoded(); 
    return raw; 
} 


private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { 
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
    byte[] encrypted = cipher.doFinal(clear); 
    return encrypted; 
} 

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception { 
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
    byte[] decrypted = cipher.doFinal(encrypted); 
    return decrypted; 
} 

public static String toHex(String txt) { 
    return toHex(txt.getBytes()); 
} 
public static String fromHex(String hex) { 
    return new String(toByte(hex)); 
} 

public static byte[] toByte(String hexString) { 
    int len = hexString.length()/2; 
    byte[] result = new byte[len]; 
    for (int i = 0; i < len; i++) 
     result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue(); 
    return result; 
} 

public static String toHex(byte[] buf) { 
    if (buf == null) 
     return ""; 
    StringBuffer result = new StringBuffer(2*buf.length); 
    for (int i = 0; i < buf.length; i++) { 
     appendHex(result, buf[i]); 
    } 
    return result.toString(); 
} 

private final static String HEX = "ABCDEF"; 
private static void appendHex(StringBuffer sb, byte b) { 
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f)); 
} 

回答

1

兩點:

1)toByte()方法目前尚不清楚它試圖這樣做,但我敢打賭,這是錯誤的,因爲行

int len = hexString.length()/2; 

是(比如說)

2)在不指定使用字符集的情況下,不能依賴將stings轉換爲字節數組。不同的區域設置和不同的運行機器可能具有不同的默認字符集。您應該在算法中使用str.getBytes(「UTF8」)。

+0

我會做更多的測試,但Charset似乎是一個問題... :) – svenkapudija 2011-03-05 23:34:41

+0

正確...它的作品,然後在薑餅2.3),但不是Froyo(2.2),反之亦然。如果我刪除字符集參數,它在2.2上工作,但不在2.3上。 – svenkapudija 2011-03-06 20:46:46

+0

以下是同樣的問題 - 那麼解決方案是什麼?使用其他一些算法? http://stackoverflow.com/questions/4536241/aes-gingerbread – svenkapudija 2011-03-07 13:32:40

1

NickT說:「要給的3相同的結果爲長度6和7(說)的字符串」 我想,在這種情況下HEX字符串的長度永遠是偶數(參見函數appendHex)