2012-11-03 285 views
0
SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method. 

String stringToEncrypt = "mypassword"; 
byte[] realiv = new byte[16]; 
random.nextBytes(realiv); 
Cipher ecipher = Cipher.getInstance("AES"); 

SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method. 

byte[] realiv = new byte[16]; 
random.nextBytes(realiv);  

byte[] secret = "somelongsecretkey".getBytes(); 
SecretKeySpec secretKey = new SecretKeySpec(secret, "AES"); 
ecipher.init(Cipher.ENCRYPT_MODE, secretKey, random); 
byte[] encryptedData = ecipher.doFinal(); 

init()只接受3個參數。我需要一種方法來這樣做:Android:使用AES加密字符串256位加密使用iv和密鑰

ecipher.init(Cipher.ENCRYPT_MODE, stringToEncrypt, secretKey, random); 

回答

4

一般而言,您不需要爲具有確定性行爲的算法生成隨機數的內容。此外,當您使用ECB塊模式時,不需要IV,這是Java默認的模式。準確地說,在Cipher.getInstance("AES")中,Java默認爲"AES/ECB/PKCS5Padding"

所以,你應該用這樣的代碼行:

// lets use the actual key value instead of the platform specific character decoding 
byte[] secret = Hex.decodeHex("25d6c7fe35b9979a161f2136cd13b0ff".toCharArray()); 

// that's fine 
SecretKeySpec secretKey = new SecretKeySpec(secret, "AES"); 

// SecureRandom should either be slow or be implemented in hardware 
SecureRandom random = new SecureRandom(); 

// first create the cipher 
Cipher eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

// filled with 00h characters first, use Cipher instance so you can switch algorithms 
byte[] realIV = new byte[eCipher.getBlockSize()]; 

// actually fill with random 
random.nextBytes(realIV); 

// MISSING: create IvParameterSpec 
IvParameterSpec ivSpec = new IvParameterSpec(realIV); 

// create the cipher using the IV 
eCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); 

// NOTE: you should really not encrypt passwords for verification 
String stringToEncrypt = "mypassword"; 

// convert to bytes first, but don't use the platform encoding 
byte[] dataToEncrypt = stringToEncrypt.getBytes(Charset.forName("UTF-8")); 

// actually do the encryption using the data 
byte[] encryptedData = eCipher.doFinal(dataToEncrypt); 

現在看起來好多了。我使用Apache commons編解碼器來解碼十六進制字符串。

請注意,您需要將realIV保存爲encryptedData,並且您沒有包含完整性保護,例如,一個MAC(對於密碼,你可能不需要那個)。

+0

確定這是太多的錯字和等,很抱歉的許多編輯,我要外面實際*喚醒*。 –

+1

AES-256定義了128位塊大小和256位密鑰大小的Rijndael算法的一個版本。你剛纔定義了一個32位十六進制char = 16字節= 128位的密鑰。如果您有128位密鑰,則不能(直接)使用AES-256。 –

+0

'IvParameterSpec ivSpec = new IvParameterSpec(realIV);'那條線做到了 – KJW