I have a Java HTTP server which receive messages from a java client.
我有一个Java HTTP服务器,它接收来自Java客户机的消息。
Both server and client use same Encrypter class:
服务器和客户端都使用相同的加密类:
public class Encrypter {
private Cipher cipher; //The encryption cipher object
public static final String ALGORITHM = "Blowfish"; //Encryption Algorithm
/**
* Constructor
*/
public Encrypter()
{
try {
initlizeCipher();
} catch (Throwable e) {
ServerSettings.LOG.logError(e);
e.printStackTrace();
}
}
/**
* Initialize the Cipher object
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
*/
private void initlizeCipher() throws NoSuchAlgorithmException, NoSuchPaddingException
{
cipher = Cipher.getInstance(ServerSettings.ALGORITHM);
}
/**
* Encrypt a String
* @param string String to encrypt
* @return an encrypted String
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws UnsupportedEncodingException
*/
public synchronized String encrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
{
cipher.init(Cipher.ENCRYPT_MODE, ServerSettings.SECRECT_KEY_SPEC);
byte[] stringBytes = string.getBytes("UTF-8");
byte[] encryptedBytes = cipher.doFinal(stringBytes);
return Base64.encodeBytes(encryptedBytes);
}
/**
* Decrypt a String
* @param string String to decrypt
* @return a decrypted String
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws IOException
*/
public synchronized String decrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException
{
cipher.init(Cipher.DECRYPT_MODE, ServerSettings.SECRECT_KEY_SPEC);
byte[] decryptedBytes = Base64.decode(string.getBytes());
byte[] encryptedBytes = cipher.doFinal(decryptedBytes);
return new String(encryptedBytes,"UTF-8");
}
}
i'm sending message to server through POST method when the variables being sent are: m=encryptedMessage.
当发送的变量为:m=encryptedMessage时,我将通过POST方法向服务器发送消息。
from some reason i always get the
出于某种原因,我总是得到。
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
and i'm not able to decrypt the message received on the server side..
我无法解密服务器端收到的消息。
i thought at first that maybe the message is broken but it doesn't..
我一开始以为可能是消息坏了,但是没有。
Any Ideas ?
什么好主意吗?
UPDATE1:
UPDATE1:
The weird thing is that some messages to the server are decrypted properly and some return that error. Good message:
奇怪的是,一些对服务器的消息被正确解密,一些消息返回错误。好的消息:
zuhRpmbtH0xSmv6cnBFkAxaGFmRbDP/97LwF4bcDyhANCTLb4afBzFpP3GI1pGFLok03GRQVCwi81Hsp bCpGtuoIVY9cqWYDzNFgOCx5w2sboR2Qx6oxtTSIFIzj1XadQdk9V8lCxcCVVYEH8vA3tph63wU6qJOo OyROz0OJauLBEiWbn5OUQxJ7Yz9Qc1wzl8z7UQb71v4pswF69c1CM/LWWmAzBDCjlRQ5YIB9wN8mBgoC t8Ngt38XkCg/yRHh0EpXYQfrgP6Ls5I8/FY8BQorMy/le5y2
Bad message:
坏消息:
cjj7yzW v3NDtbIJXurrrf318DcY PBk2inzSfz qoIaTKns2tWvR7ftOKK30XY VAlXDrQlyTLatgKA S4IkAIK3lXQKNcwPh87CybHrTqD3HWEM3tqkpVWdB7GNmpHYsITTLrWsBvaMeDcXEr/gr9KYSZ0ks0gR z12jHxPiZoSKHdy5nZ4zShHUy/wlkslmjFvA1G8A15nTVBhjBI GWSh54tyBZF113lL pm5eZNkZrqzo RWI2QAjfqNPzCpV0tqd/pEO70vdSLbCYi7V0bVQNW2KpBv3Hj3VOTCP92k62/iQhIY4F VuMo2UTgGWV 1fqoelrl/eelAvsZO8YNC5/2KTKw2sDFaTOwW9R12AgeyzOuhkKQQro2Umd0KoiGnYL9AaQ6 T2MBnLK ZyROHh3cvI T9chPlGfmUHbCN2f3pHoF5rb383KpJNjvlnmnwtaEhQYw8TQjj4PLenK24Hpcs4 wO8gu XSrUglFzLIkkwjvsA5AyTHx/jP9AwMSnWjDwco184YQGAePeM8PYy42oMOaw7Pg/3jWFy1uOzFok2LN9 RJWv1iyXejh5s9zXoAT3kywICQygK2YTLZNIS1d5lc0H0f15EN6itZhaR0YnslhYGmH1KcNwdMWhBKsf PytWnK0N8AzUVzt4P4mtmGSuaLi2t54J2pv7m7/c6WjTi1/E16rd3QyWkmXrghSshOJNRRwcydlhhTLH drHTEFaXSPZyVFqlaFu4 f5kxiBa6ewglKHe6zbmRyM15Mq3lRj8Ab/RWBd2tgvaEO/vhw
Both of these message are sent in the same way and are printed to the System.Out for testing. As u can see the bad message have spaces from some reason while the good message doesn't what probably gives the block error message.. any idea how to solve it ?
这两个消息都以相同的方式发送,并被打印到系统中。为测试。当你看到坏消息时,有一些原因,而好的消息不可能给出块错误信息。知道怎么解决吗?
Update 2:
更新2:
After digging into my code I've found out that my problem is inside the function that parse the POST method parameters. I can't say i'm an expert in encoding but there is some problem with passing Base64 encoding throw POST URLEcoding..
在深入挖掘我的代码之后,我发现我的问题在于解析POST方法参数的函数。我不能说我是编码方面的专家,但是通过Base64编码抛出的URLEcoding是有问题的。
This is my parsing code which after getting URLDecode goes to my Encrypter for decrypt:
这是我的解析代码,在得到URLDecode之后进入我的Encrypter进行解密:
private void parseQuery(String query, HashMap parameters) throws UnsupportedEncodingException {
private void parseQuery(字符串查询、HashMap参数)抛出UnsupportedEncodingException
if (query != null) {
String pairs[] = query.split("[&]");
for (String pair : pairs)
{
String param[] = pair.split("[=]");
String key = null;
String value = null;
if (param.length > 0)
key = URLDecoder.decode(param[0], "UTF-8");//System.getProperty("file.encoding"));
if (param.length > 1)
value = URLDecoder.decode(param[1], "UTF-8");//System.getProperty("file.encoding"));
if (parameters.containsKey(key))
{
Object obj = parameters.get(key);
if(obj instanceof List<?>)
{
@SuppressWarnings("unchecked")
List<String> values = (List<String>)obj;
values.add(value);
}
else if(obj instanceof String)
{
List<String> values = new ArrayList<String>();
values.add((String)obj);
values.add(value);
parameters.put(key, values);
}
}
else
parameters.put(key, value);
}
}
}
}
Any Ideas ?
什么好主意吗?
3 个解决方案
#1
1
I faced the similar problem yesterday. I solved it by encoding the bytes to base64 at client side and decoding it before use at the server side.
我昨天遇到了类似的问题。我通过在客户端将字节编码到base64并在服务器端使用之前对其进行解码,从而解决了这个问题。
Refer to this link - [cipher]: http://www.velocityreviews.com/forums/t645364-java-string-encryption-decryption.html
请参考这个链接- [cipher]: http://www.velocityreviews.com/forums/t645364-java- string-encryption.html。
SO basically this is what you need to do -
基本上这就是你需要做的。
At client side
在客户端
- Get the byte array from a string
- 从字符串获取字节数组。
- Encrypt it.
- 加密它。
- Encode the byte array using base64 encoding
- 使用base64编码对字节数组进行编码。
At server side
在服务器端
- Decode the base64 encoded data to get a byte array
- 解码base64编码的数据以获得一个字节数组。
- Decrypt the byte array.
- 解密的字节数组。
- Construct a string using this byte array.
- 使用这个字节数组构造一个字符串。
#2
1
Finely after lots of testing and crying :) , I've found what i was suspecting from the beginning.
经过大量的测试和哭泣:),我从一开始就发现了我的怀疑。
When passing data through URL (POST\GET whatever) you must first URL-Encode it first on your client side before sending it, and URL-Decoding on the server side before processing it.
当通过URL传递数据(POST\GET)时,您必须首先在客户端对其进行URL编码,然后将其发送到服务器端,然后在处理它之前在服务器端进行URL解码。
Thanks to Java's great URLEncoder and URLDecoder class you can easily do it:
多亏了Java的伟大的URLEncoder和URLDecoder类,你可以很容易地做到:
//Before sending encode your data for URL - Client side URLEncoder.encode(your_data,charset_name); //charset_name - the recommendation is to use "UTF-8"
//在发送你的数据为URL -客户端URLEncoder.encode(your_data,charset_name)编码之前;//charset_name -推荐使用“UTF-8”
//After receiving the data - decode you data for process - Server side URLDecoder.decode(your_data,charset_name); //charset_name - the recommendation is to use "UTF-8"
//在接收到数据后,将数据解码为process - Server side URLDecoder.decode(your_data,charset_name);//charset_name -推荐使用“UTF-8”
#3
0
To narrow down the alternatives, place download and unlimited strength JCE policy jar from Oracle/Sun and place it under your JVM. from my experience with java cryptography, 90% of the problems you will face when encrypting come from the fact that the JVM/JDK is ship with a strong but limited strength policy and whenever you try to use and 252k or more algorithms, the JVM start throwing some weird errors.
要缩小选择的范围,可以从Oracle/Sun中下载和限制JCE策略jar,并将其放置在JVM下。从我对java密码学的经验来看,你在加密时所面临的90%的问题都来自于一个事实,即JVM/JDK是一种强大但有限的强度策略,当你尝试使用和252k或更多的算法时,JVM开始抛出一些奇怪的错误。
#1
1
I faced the similar problem yesterday. I solved it by encoding the bytes to base64 at client side and decoding it before use at the server side.
我昨天遇到了类似的问题。我通过在客户端将字节编码到base64并在服务器端使用之前对其进行解码,从而解决了这个问题。
Refer to this link - [cipher]: http://www.velocityreviews.com/forums/t645364-java-string-encryption-decryption.html
请参考这个链接- [cipher]: http://www.velocityreviews.com/forums/t645364-java- string-encryption.html。
SO basically this is what you need to do -
基本上这就是你需要做的。
At client side
在客户端
- Get the byte array from a string
- 从字符串获取字节数组。
- Encrypt it.
- 加密它。
- Encode the byte array using base64 encoding
- 使用base64编码对字节数组进行编码。
At server side
在服务器端
- Decode the base64 encoded data to get a byte array
- 解码base64编码的数据以获得一个字节数组。
- Decrypt the byte array.
- 解密的字节数组。
- Construct a string using this byte array.
- 使用这个字节数组构造一个字符串。
#2
1
Finely after lots of testing and crying :) , I've found what i was suspecting from the beginning.
经过大量的测试和哭泣:),我从一开始就发现了我的怀疑。
When passing data through URL (POST\GET whatever) you must first URL-Encode it first on your client side before sending it, and URL-Decoding on the server side before processing it.
当通过URL传递数据(POST\GET)时,您必须首先在客户端对其进行URL编码,然后将其发送到服务器端,然后在处理它之前在服务器端进行URL解码。
Thanks to Java's great URLEncoder and URLDecoder class you can easily do it:
多亏了Java的伟大的URLEncoder和URLDecoder类,你可以很容易地做到:
//Before sending encode your data for URL - Client side URLEncoder.encode(your_data,charset_name); //charset_name - the recommendation is to use "UTF-8"
//在发送你的数据为URL -客户端URLEncoder.encode(your_data,charset_name)编码之前;//charset_name -推荐使用“UTF-8”
//After receiving the data - decode you data for process - Server side URLDecoder.decode(your_data,charset_name); //charset_name - the recommendation is to use "UTF-8"
//在接收到数据后,将数据解码为process - Server side URLDecoder.decode(your_data,charset_name);//charset_name -推荐使用“UTF-8”
#3
0
To narrow down the alternatives, place download and unlimited strength JCE policy jar from Oracle/Sun and place it under your JVM. from my experience with java cryptography, 90% of the problems you will face when encrypting come from the fact that the JVM/JDK is ship with a strong but limited strength policy and whenever you try to use and 252k or more algorithms, the JVM start throwing some weird errors.
要缩小选择的范围,可以从Oracle/Sun中下载和限制JCE策略jar,并将其放置在JVM下。从我对java密码学的经验来看,你在加密时所面临的90%的问题都来自于一个事实,即JVM/JDK是一种强大但有限的强度策略,当你尝试使用和252k或更多的算法时,JVM开始抛出一些奇怪的错误。