2013-03-05 83 views
0

我在这里有一个简单的代码,代码使用sun.misc.BASE64Encoder和sun.misc.BASE64Decoder,这些在Eclipse Java 7.0中不可用,我想使代码如此它使用了Apache下议院底座64,仍然做同样的事情,sun.misc.BASE64到apache commons

变量

private static final String ALGORITHM = "AES"; 
private static final byte[] keyValue = "2H5a1r5i6s3h8C1h".getBytes(); 

原始代码

public static String AESencrypt(String valueToEnc) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
    String encryptedValue = new BASE64Encoder().encode(encValue); 
    return encryptedValue; 
} 

public static String AESdecrypt(String encryptedValue) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.DECRYPT_MODE, key); 
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue); 
    byte[] decValue = c.doFinal(decordedValue); 
    String decryptedValue = new String(decValue); 
    return decryptedValue; 
} 

试图修改Apache的公共代码

public static String AESencrypt(String valueToEnc) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
    String encryptedValue = new Base64().encodeBase64(encValue).toString(); 
    return encryptedValue; 
} 

public static String AESdecrypt(String encryptedValue) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.DECRYPT_MODE, key); 
    byte[] decordedValue = new Base64().decodeBase64(encryptedValue); 
    byte[] decValue = c.doFinal(decordedValue); 
    String decryptedValue = new String(decValue); 
    return decryptedValue; 
} 

原来的代码工作正常,新的代码抛出以下异常,

异常线程 “main” javax.crypto.IllegalBlockSizeException : 当用加密密码 在com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750) at com.sun.crypto.provider.CipherCore.doFinal(Ciph)解密时,输入长度必须是16的倍数erCore.java:676) 处 trial2.encrypt.AESdecrypt com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313) 在javax.crypto.Cipher.doFinal(Cipher.java:2087) (encrypt.java:28)在 trial2.encrypt.main(encrypt.java:37) Java结果:1

我怎样才能解决这个问题,而不改变初始密码太多了,这里的几行并没有问题。是否有可能完全消除Base64encoding一步,使其只这样的加密工作:

public static String AESencrypt(String valueToEnc) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
    return encValue.toString(); 
} 

public static String AESdecrypt(String encryptedValue) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.DECRYPT_MODE, key); 
    byte[] decValue = c.doFinal(encryptedValue.getBytes()); 
    String decryptedValue = new String(decValue); 
    return decryptedValue; 
} 

上面的代码也有类似的异常,如第二码:

异常线程“main” javax.crypto.IllegalBlockSizeException: 当使用填充密码 解密时,输入长度必须是16的倍数com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750) at com.sun.crypto.provider.CipherCore .doFinal(CipherCore.java:676) at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313) at javax.crypto.Cipher.doFinal(Cipher.java:2087)at trial2.encrypt.AESdecrypt(encrypt.java:26)at trial2.encrypt.main(encrypt.java:35)Java结果:1

请帮忙TYVM

+0

建议:去掉密码并做一些测试。它们是否产生相同的值等等,这应该是可以解决的! – 2013-03-05 12:31:31

+0

永远不会*使用Sun内部类,它们可能会在没有警告的情况下被删除或更改。它们不是官方Java API的一部分。请注意,如果您选择特定的JRE或JDK而不是运行时环境,则这些类将再次可用(同样,因为运行时环境仅将这些类用于实现目的而不是API) – 2013-03-05 23:19:48

+1

不要只将“AES”指定为算法,如它可能会为特定提供商返回不同的默认值。在Sun/Oracle默认情况下,它会返回“AES/ECB/PKCS5Padding”,这是不安全的(保密的最低要求模式是CBC模式)。 – 2013-03-05 23:21:41

回答

2

的错误是在你的加密方法。下面的代码是错误的:

byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
String encryptedValue = new Base64().encodeBase64(encValue).toString(); 

要调用一个字节数组,你想要什么,不会做toString()!相反,请尝试:

byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
String encryptedValue = Base64.encodeBase64String(encValue); 

这应该可以正常工作。

+0

似乎工作,是否有必要进行base64encoding步骤?我的意思是我不明白它做了什么。 – chettyharish 2013-03-05 12:50:32

+2

如果您希望将密文存储为字符串,base64编码步骤是您可以使用的选项之一。另一个通常选择的选项是base16(a.k.a十六进制)。根据您的使用情况,您可以将密文保留为字节数组。通常情况下,转换为字符串仅用于传输数据,特别是在Web环境中。 – 2013-03-05 13:18:33

+0

ty的帮助,猜猜我需要做到保存到数据库。 – chettyharish 2013-03-05 15:26:44

相关问题