2012-11-03 287 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