2013-03-26 56 views
0

我需要为每次运行AES(在JAVA中)生成不同的令牌,因为我所做的是我附加了使用当前系统时间加密的字符串,使用java中的System.currentTimeMillis()并将两者分开他们使用管道字符“|”。但是,我们面临的问题是,每次运行时加密的字符串都是相同的,并且解密时我得到正确的字符串。为什么会这样呢?使用AES加密的令牌不会改变

代码加密:

import java.security.Key; 

import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 

import org.apache.commons.codec.binary.Base64; 

public class AESEncryptor { 
    private static final String ALGO = "AES"; 
    private final static byte[] keyValue =new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't','S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' }; 

    public static String encrypt(String Data) throws Exception { 
      Key key = generateKey(); 
      Cipher c = Cipher.getInstance(ALGO); 
      c.init(Cipher.ENCRYPT_MODE, key); 
      byte[] encVal = c.doFinal(Data.getBytes()); 
      byte[] encryptedValue = Base64.encodeBase64(encVal); 
      String encryptedPass = new String (encryptedValue); 
      return encryptedPass; 
     } 

    public static String decrypt(String encryptedData) throws Exception { 
     Key key = generateKey(); 
     Cipher c = Cipher.getInstance(ALGO); 
     c.init(Cipher.DECRYPT_MODE, key); 
     Base64.decodeBase64(encryptedData); 
     byte[] decordedValue = Base64.decodeBase64(encryptedData); 
     byte[] decValue = c.doFinal(decordedValue); 
     String decryptedValue = new String(decValue); 
     return decryptedValue; 
    } 

    private static Key generateKey() throws Exception { 
     Key key = new SecretKeySpec(keyValue, ALGO); 
     return key; 
    } 

} 


1st run : 
argument passed to encrypt : somepassword|1364311519852 
encrypted string : 5pQ1kIC+8d81AD7zbLOZA==(encrypted string) 
decrypted string : somepassword|1364311519852 

2nd run : 
argument passed to encrypt : somepassword|1364311695048 
encrypted string : 5pQ1kIC+8d81AD7zbLOZA==(same encrypted string as before) 
decrypted string : somepassword|1364311695048 

谁能帮为什么会发生这样的吗?

+1

你的密文是从“somestring | 1364300620387”加密的简称,也不能解密回它。如果我们假设你的模式不使用填充,即使Base64应该比原始字节长至少1.25倍。不可能。 – jbtule 2013-03-26 12:52:41

+0

我在上面提到的密文是虚拟的,实际的是24个字符。我给出了一个虚拟的例子,以举例说明我面临的情况。 – 2013-03-26 13:38:51

+1

是的,当你有目的地给出错误的信息,没有人可以帮助你。 – jbtule 2013-03-26 13:58:21

回答

0

虽然我仍然不相信你可以解密你的输出(我相信@ user93353提供的输出)。 ECB模式并不理想,您应该切换到CBC。

private static final String ALGO = "AES/CBC/PKCS7Padding"; 

添加一个随机产生的IV,前置到您的密文,和你的密文将完全看起来就像是随机的数据,即使你一遍又一遍加密相同的文字。

既然你提到了token这个词,这表明你使用密文作为真实性,这不是aes自己提供的。我认为你应该强烈地研究authenticated encryption,特别是加密(aes-cbc)-then-mac(hmac),在那里你可以将你的密文的mac加密,iv加密你的密文。

+0

它的工作..谢谢@jbtule – 2013-03-27 09:05:57