所以我正在创建一个将安全消息发送到指定IP地址的应用程序。我使用AES加密消息,该部分工作得很好。我能够加密消息并在发送消息之前解密它。但是,当我尝试解密已从服务器收到的邮件时,我无法解密它。它以加密形式显示。
我收到此错误" java.lang.NumberFormatException:无效的int:" ne""我认为它可能与字符编码或其他什么有关?通过网络发送时,字符串是否以任何方式被更改?
以下是可能与此问题相关的摘要。
public static String encrypt(String seed, String cleartext)
throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted)
throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
public static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2 * buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
这是我对要显示的消息进行解密的地方。
while (!goOut) {
if (dataInputStream.available() > 0) {
incoming = dataInputStream.readUTF();
if(encrypt == true) {
try{
msgLog += AESHelper.decrypt(seed,incoming);
} catch (Exception e) {
e.printStackTrace();
}
} else msgLog += incoming;
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
chatMsg.setText(msgLog);
}
});
这是加密消息:
OnClickListener buttonEncryptOnClickListener = new OnClickListener() {
public void onClick(View v) {
if (chatClientThread == null) {
return;
}
if (editTextSay.getText().toString().equals("")) {
return;
}
if(!editTextSay.getText().toString().equals("")){
String message = editTextSay.getText().toString();
encrypt = true;
int secLvl = Integer.parseInt(editTextSecurity.getText().toString());
String encryptedMsg;
try {
encryptedMsg = AESHelper.encrypt(seed, message);
textEncryptedmsg.setText(encryptedMsg);
textEncryptedmsg.setVisibility(View.VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
这是发送消息:
OnClickListener buttonSendOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (editTextSay.getText().toString().equals("")) {
return;
}
if(chatClientThread==null){
return;
}
if (encrypt == true){
chatClientThread.sendMsg(textEncryptedmsg.getText().toString() + "\n");
} else {
chatClientThread.sendMsg(editTextSay.getText().toString() + "\n");
}
editTextSay.setText("");
textEncryptedmsg.setText("");
textDecryptedmsg.setText("");
encrypt = false;
incomingmsg.setVisibility(View.VISIBLE);
}
};
答案 0 :(得分:1)
我假设你以十六进制编码的形式发送密文。 DataInputStream#readUTF()
读取single Unicode character from the stream。由于您正在发送十六进制字符,这意味着可以从两个这样的Unicode字符构造单个密文字节。
问题在于AES在块上运行。试图解密每一个单独的&#34; -byte分别无法工作。
您需要将解密方法重写为
如果您想尝试流式解密,那么您基本上有两种选择:
Cipher#update()
或CipherInputStream
。这是一个(伪代码)示例,在尝试解密之前读取整个内容:
StringBuilder incoming = new StringBuilder();
while (!goOut && ) {
incoming.append(dataInputStream.readUTF());
}
if(encrypt == true) {
try{
msgLog += AESHelper.decrypt(seed, incoming.toString());
} catch (Exception e) {
e.printStackTrace();
}
} else msgLog += incoming;
答案 1 :(得分:0)
我在不使用CipherInputStream
的情况下找到了解决问题的方法。
每当我加密消息并发送消息时,加密/解密算法都不会解密从服务器接收的消息。由于输出加密消息与我发送的消息相同,我将传入的加密消息打印到TextView
然后我将TextView
复制到String
并解密它,现在效果很好。
while (!goOut) {
if (dataInputStream.available() > 0) {
final String incoming = dataInputStream.readUTF();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
incomingmsg.setText(incoming);
mustDecrypt = incomingmsg.getText().toString();
if (encrypt)
try {
mustDecrypt = AESHelper.decrypt(seed, mustDecrypt);
msgLog += mustDecrypt;
} catch (Exception e){
e.printStackTrace();
}
else msgLog += mustDecrypt;
chatMsg.setText(msgLog);
}
});
}