2012-12-24 136 views
3

我使用密碼加密和解密的消息:Android的密碼加密/解密

public String encrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { 
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); 
    byte[] stringBytes = string.getBytes("UTF-8"); 
    byte[] encryptedBytes = cipher.doFinal(stringBytes); 
    return android.util.Base64.encodeToString(encryptedBytes, android.util.Base64.DEFAULT); 
} 

public String decrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { 
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); 
    byte[] stringBytes = android.util.Base64.decode(string.getBytes(), android.util.Base64.DEFAULT); 
    byte[] decryptedBytes = cipher.doFinal(stringBytes); 
    return new String(decryptedBytes,"UTF-8"); 
} 

出於某種原因,雖然我用的Base64編碼和解碼字符串,我仍然得到這個錯誤:

javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

我在做什麼錯?

編輯:

這是我的JSONObject - 我試圖解密 「M」:

{"m":"Cu7FR2be0E6ZP2BrZaLU2ZWQSfycNg0-fPibphTIZno\r\n"} 

奇怪的是,該錯誤只出現在Android中。我的服務器是用Java編寫的,而且我使用的是Apache Base64編碼器,它工作的很好。

+0

解密(「\ u0000的」)或某些Unicode字符將始終是 – 2012-12-24 15:11:03

+0

的嘮叨我不明白:) –

+0

這就是問題所在:) – 2012-12-24 15:55:00

回答

2

您需要首先轉換Base-64。

CODEED = encrypt(Base64.encode(MYSTRING,Base64.DEFAULT));

MYSTRING = Base64.decode(decrypt(CODEED),Base64.DEFAULT);

這裏是一個鏈接http://androidcodemonkey.blogspot.com/2010/03/how-to-base64-encode-decode-android.html

+0

我現在得到了java.io.IOException:錯誤的Base64輸入字符小數點45在數組中的位置31 - 在Base解碼 –

+0

如果你不介意,你可以分享你的字符串嗎? – Mert

+0

我已經把它添加到我的職位 –

3

你的代碼似乎確定以我來說,你可以嘗試添加「UTF-8」之前解碼。

byte[] stringBytes = android.util.Base64.decode(string.getBytes("UTF-8"), android.util.Base64.DEFAULT); 

編輯

這是做一個使用BouncyCastle的和基於密碼的AES加密加密/解密的例子安全的實用工具類。

public class SecurityUtils { 

public static final String KEY_DERIVATION_ALGORITHM = "PBKDF2WithHmacSHA1"; 

private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; 

private static final String DELIMITER = "]"; 

private static final int KEY_LENGTH = 256; 

private static final int ITERATION_COUNT = 1000; 

private static final int SALT_LENGTH = 8; 

private static SecureRandom random = new SecureRandom(); 

static { 
    Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider()); 
} 


public static String encrypt(Context context, String plaintext) 
     throws Exception { 
    byte[] salt = generateSalt(); 
    return encrypt(plaintext, getKey(salt, getPassword(context)), salt); 
} 

private static String encrypt(String plaintext, SecretKey key, byte[] salt) 
     throws Exception { 
    try { 
     Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC"); 

     byte[] iv = generateIv(cipher.getBlockSize()); 
     IvParameterSpec ivParams = new IvParameterSpec(iv); 

     cipher.init(Cipher.ENCRYPT_MODE, key, ivParams); 
     byte[] cipherText = cipher.doFinal(plaintext.getBytes("UTF-8")); 

     if (salt != null) { 
      return String.format("%s%s%s%s%s", 
        new String(Base64.encode(salt)), DELIMITER, new String(
          Base64.encode(iv)), DELIMITER, new String(
          Base64.encode(cipherText))); 
     } 

     return String.format("%s%s%s", new String(Base64.encode(iv)), 
       DELIMITER, new String(Base64.encode(cipherText))); 
    } catch (Throwable e) { 
     throw new Exception("Error while encryption", e); 
    } 
} 

public static String decrypt(Context context, String ciphertext) 
     throws Exception { 
    return decrypt(ciphertext, getPassword(context)); 
} 

private static String decrypt(String ciphertext, String password) 
     throws Exception { 
    String[] fields = ciphertext.split(DELIMITER); 
    if (fields.length != 3) { 
     throw new IllegalArgumentException("Invalid encypted text format"); 
    } 
    try { 
     byte[] salt = Base64.decode(fields[0]); 
     byte[] iv = Base64.decode(fields[1]); 
     byte[] cipherBytes = Base64.decode(fields[2]); 

     SecretKey key = getKey(salt, password); 
     Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC"); 
     IvParameterSpec ivParams = new IvParameterSpec(iv); 
     cipher.init(Cipher.DECRYPT_MODE, key, ivParams); 
     byte[] plaintext = cipher.doFinal(cipherBytes); 
     String plainrStr = new String(plaintext, "UTF-8"); 

     return plainrStr; 
    } catch (Throwable e) { 
     throw new Exception("Error while decryption", e); 
    } 
} 

private static String getPassword(Context context) { 

    return "My secret password"; 
} 

private static SecretKey getKey(byte[] salt, String password) 
     throws Exception { 
    try { 
     KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 
       ITERATION_COUNT, KEY_LENGTH); 
     SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(
       KEY_DERIVATION_ALGORITHM, "BC"); 
     byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); 
     return new SecretKeySpec(keyBytes, "AES"); 
    } catch (Throwable e) { 
     throw new Exception("Error while generating key", e); 
    } 
} 

private static byte[] generateIv(int length) { 
    byte[] b = new byte[length]; 
    random.nextBytes(b); 

    return b; 
} 

private static byte[] generateSalt() { 
    byte[] b = new byte[SALT_LENGTH]; 
    random.nextBytes(b); 

    return b; 
} 

}

+0

嘗試過..沒有工作 –

+0

你可以試試這個類,只是調整它滿足您的需求並將BouncyCastle罐子添加到您的項目中。 – iTech

+0

考慮到http://android-developers.blogspot.pt/2013/02/using-cryptography-to-store-credentials.html能夠正常工作嗎? – Spartako