2013-02-18 165 views
6

我从http://www.ravenblast.com/index.php/blog/android-password-text-encryption/得到了这段代码,尽管它有效,但我越来越怀疑它不够安全。根据其他来源,似乎没有任何初始化向量。这种AES加密是否足够安全?

public static String encrypt(String toEncrypt, byte[ ] key) throws Exception { 
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
    byte[ ] encryptedBytes = cipher.doFinal(toEncrypt.getBytes()); 
    String encrypted = Base64.encodeBytes(encryptedBytes); 
    return encrypted; 
} 

public static String decrypt(String encryptedText, byte[ ] key) throws Exception { 
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
    byte[] toDecrypt = Base64.decode(encryptedText); 
    byte[] encrypted = cipher.doFinal(toDecrypt); 
    return new String(encrypted); 
} 
+2

你需要一个IV和MAC。在面对主动攻击者时,在加密 - 然后MAC方案中使用MAC或使用专门的身份验证加密非常重要。否则攻击者可能会诱骗你为他解密一条消息。填充神谕是一种实际的攻击。如果这是欧洲央行(我对API的了解不够熟悉),您还需要切换到更好的模式。 – CodesInChaos 2013-02-18 13:46:23

+2

使用'getBytes()'也不好,因为它使用平台/文化相关的编码。改用UTF-8。 – CodesInChaos 2013-02-18 13:47:29

回答

9

是的,它不是很安全。没有IV,因为没有块链接

AES算法只能加密128个字节的块,不管密钥的大小(它是不相关的)。如何将这些街区链接在一起是另一个问题。最简单的方法是将每个块与其他块分开加密(ECB mode),就像它们是单独的消息一样。我链接的维基百科文章告诉你何时和为什么这是不安全的,其他方法(即CBC mode)是首选。

当你做Cipher cipher = Cipher.getInstance("AES");你给了一个在ECB mode的AES密码。没有即时危险,但如果你的消息具有重复模式,这可能导致像以下几种情况:

原文:enter image description here加密:encrypted