Using tomcat, I have two web-applications i.e app1 and app2. I sent url from app1 in encrypted form (using below code) to app2 . Then at app2 I decrypted this encrypted url. But am getting below exception at line 50 of decryp
method.
使用tomcat,我有两个web应用程序I。e app1和app2。我以加密的形式(使用下面的代码)将url从app1发送到app2。然后在app2我解密了这个加密的url。但是我在解密方法的第50行得到了下面的异常。
"Getting javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher"
Though for debugging when I try to decrypt(using same code) the encrypted url at app1, it works fine. But not able to figure out what causing this exception at app2?
虽然在我试图解密(使用相同的代码)时进行调试,但在app1上的加密url可以正常工作。但是无法弄清楚是什么原因导致app2上的异常?
Here is the code
这是代码
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AESEncryptionDecryptionTest {
private static final String ALGORITHM = "AES";
private static final String myEncryptionKey = "ThisIsFoundation";
private static final String UNICODE_FORMAT = "UTF8";
public static String encrypt(String valueToEnc) throws Exception {
Key key = generateKey();
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 decrypt(String encryptedValue) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue);
byte[] decValue = c.doFinal(decordedValue);//////////LINE 50
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
byte[] keyAsBytes;
keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
Key key = new SecretKeySpec(keyAsBytes, ALGORITHM);
return key;
}
public static void main(String[] args) throws Exception {
String value = "password1";
String valueEnc = AESEncryptionDecryptionTest.encrypt(value);
String valueDec = AESEncryptionDecryptionTest.decrypt(valueEnc);
System.out.println("Plain Text : " + value);
System.out.println("Encrypted : " + valueEnc);
System.out.println("Decrypted : " + valueDec);
}
}
3 个解决方案
#1
10
Works on my machine. Does it help if you use `UNICODE_FORMAT' in every instance where you transform bytes to Strings and vice versa? This line could be a problem:
在我的机器上工作。如果在每个实例中都使用“UNICODE_FORMAT”将字节转换为字符串,反之亦然,这是否会有所帮助?这条线可能是个问题:
byte[] encValue = c.doFinal(valueToEnc.getBytes());
should be
应该是
byte[] encValue = c.doFinal(valueToEnc.getBytes(UNICODE_FORMAT));
Anyway, if you use "AES" as the algorithm and you use the JCE, the algorithm actually being used will be "AES/ECB/PKCS5Padding". Unless you are 100% sure about what you are doing, ECB shouldn't be used for anything. I'd recommend to always specify the algorithm explicitly in order to avoid such confusion. "AES/CBC/PKCS5Padding" would be a good choice. But watch out, with any reasonable algorithm you will also have to provide and manage an IV.
无论如何,如果你使用"AES"作为算法,你使用JCE,实际使用的算法将是"AES/ECB/PKCS5Padding。除非你百分之百确定自己在做什么,否则欧洲央行不应该被用来做任何事情。为了避免这种混淆,我建议始终明确地指定算法。“AES/CBC/PKCS5Padding(简称为AES)”是个不错的选择。但要小心,任何合理的算法你也必须提供和管理一个IV。
Using an ECB cipher is even less desirable in the context of encrypting passwords, which is what you seem to be doing with your encryption if I interpret your example correctly. You should use password-based encryption as specified in PKCS#5 for that purpose, in Java this is provided for you in SecretKeyFactory. Be sure to use "PBKDF2WithHmacSHA1" with a high enough iteration count (anything ranging from ~ 5-20 000, depends on your target machine) for using passwords to derive symmetric keys from them.
在加密密码的上下文中,使用欧洲央行密码甚至更不可取,如果我正确地解释了您的示例,您似乎正在使用您的加密。您应该在PKCS#5中为该目的使用基于密码的加密,在Java中,这是在SecretKeyFactory中为您提供的。确保使用“PBKDF2WithHmacSHA1”具有足够高的迭代计数(任何值在5- 20,000之间,取决于您的目标计算机)来使用密码从它们派生对称密钥。
The same technique can be used if it is actually password storage instead of password encryption what you are trying to achieve.
如果实际上是密码存储而不是密码加密,也可以使用相同的技术。
#2
-1
I was seeing this error (with the password getting through just fine like you say here) when double-decrypting a value. Be sure to check to see if you are doing the decrypting more than once. (mine was multiple of 8 in the error, but I was using a different scheme there...) In my case I was decrypting when reading a file and then decrypting again when filling out a field. (desktop app)
当双解密一个值时,我看到了这个错误(密码就像你在这里说的那样)。一定要检查是否正在进行不止一次的解密。(我的错误是8的倍数,但我用的是另一种方法……)在我的例子中,我在读取文件时解密,然后在填写字段时再次解密。(桌面应用程序)
#3
-3
This error indicates that you used choice combination requires 16 characters source text only. If you want to encrypt a password, you can truncate or pad the original password to 16-char for encryption, and trim after decryption. This way must limit real password not longer than 16-char, but you may apply longer used password to confuse those who should not know your password.
这个错误表明您使用的选择组合只需要16个字符的源文本。如果您想加密一个密码,您可以截断或填充原始密码到16字符的加密,并在解密后进行修整。这种方法必须限制真实密码不超过16字符,但是您可以使用更长的使用密码来迷惑那些不应该知道您密码的人。
#1
10
Works on my machine. Does it help if you use `UNICODE_FORMAT' in every instance where you transform bytes to Strings and vice versa? This line could be a problem:
在我的机器上工作。如果在每个实例中都使用“UNICODE_FORMAT”将字节转换为字符串,反之亦然,这是否会有所帮助?这条线可能是个问题:
byte[] encValue = c.doFinal(valueToEnc.getBytes());
should be
应该是
byte[] encValue = c.doFinal(valueToEnc.getBytes(UNICODE_FORMAT));
Anyway, if you use "AES" as the algorithm and you use the JCE, the algorithm actually being used will be "AES/ECB/PKCS5Padding". Unless you are 100% sure about what you are doing, ECB shouldn't be used for anything. I'd recommend to always specify the algorithm explicitly in order to avoid such confusion. "AES/CBC/PKCS5Padding" would be a good choice. But watch out, with any reasonable algorithm you will also have to provide and manage an IV.
无论如何,如果你使用"AES"作为算法,你使用JCE,实际使用的算法将是"AES/ECB/PKCS5Padding。除非你百分之百确定自己在做什么,否则欧洲央行不应该被用来做任何事情。为了避免这种混淆,我建议始终明确地指定算法。“AES/CBC/PKCS5Padding(简称为AES)”是个不错的选择。但要小心,任何合理的算法你也必须提供和管理一个IV。
Using an ECB cipher is even less desirable in the context of encrypting passwords, which is what you seem to be doing with your encryption if I interpret your example correctly. You should use password-based encryption as specified in PKCS#5 for that purpose, in Java this is provided for you in SecretKeyFactory. Be sure to use "PBKDF2WithHmacSHA1" with a high enough iteration count (anything ranging from ~ 5-20 000, depends on your target machine) for using passwords to derive symmetric keys from them.
在加密密码的上下文中,使用欧洲央行密码甚至更不可取,如果我正确地解释了您的示例,您似乎正在使用您的加密。您应该在PKCS#5中为该目的使用基于密码的加密,在Java中,这是在SecretKeyFactory中为您提供的。确保使用“PBKDF2WithHmacSHA1”具有足够高的迭代计数(任何值在5- 20,000之间,取决于您的目标计算机)来使用密码从它们派生对称密钥。
The same technique can be used if it is actually password storage instead of password encryption what you are trying to achieve.
如果实际上是密码存储而不是密码加密,也可以使用相同的技术。
#2
-1
I was seeing this error (with the password getting through just fine like you say here) when double-decrypting a value. Be sure to check to see if you are doing the decrypting more than once. (mine was multiple of 8 in the error, but I was using a different scheme there...) In my case I was decrypting when reading a file and then decrypting again when filling out a field. (desktop app)
当双解密一个值时,我看到了这个错误(密码就像你在这里说的那样)。一定要检查是否正在进行不止一次的解密。(我的错误是8的倍数,但我用的是另一种方法……)在我的例子中,我在读取文件时解密,然后在填写字段时再次解密。(桌面应用程序)
#3
-3
This error indicates that you used choice combination requires 16 characters source text only. If you want to encrypt a password, you can truncate or pad the original password to 16-char for encryption, and trim after decryption. This way must limit real password not longer than 16-char, but you may apply longer used password to confuse those who should not know your password.
这个错误表明您使用的选择组合只需要16个字符的源文本。如果您想加密一个密码,您可以截断或填充原始密码到16字符的加密,并在解密后进行修整。这种方法必须限制真实密码不超过16字符,但是您可以使用更长的使用密码来迷惑那些不应该知道您密码的人。