将消息发送到 IP 地址后进行 AES 解密
AES decryption after sending message to IP address
所以我正在制作一个应用程序,可以将安全消息发送到指定的 IP 地址。我正在使用 AES 来加密消息,那部分效果很好。我能够在发送消息之前加密消息并解密它。但是,当我尝试解密从服务器收到的消息时,我无法解密它。它以加密形式显示。
我收到此错误 "java.lang.NumberFormatException: Invalid 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);
}
};
我假设您以十六进制编码的形式发送密文。 DataInputStream#readUTF()
读取 single Unicode character from the stream。由于您要发送十六进制字符,这意味着可以从两个这样的 Unicode 字符构造一个密文字节。
问题在于 AES 对块进行运算。尝试分别解密每个 "half" 字节是行不通的。
您需要将解密方法重写为
- 使用流式解密或
- 读取整个密文,一口气解密
如果你想尝试流式解密,那么你基本上有两个选择:
- 使用
Cipher#update()
或 的偏移版本更新 Cipher 对象的内部缓冲区
- 使用
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;
我在不使用 CipherInputStream
的情况下找到了解决问题的方法。
每当我加密一条消息并发送它时,encryption/decryption 算法不会解密从服务器收到的消息。由于输出的加密消息与我发送的消息相同,我将传入的加密消息打印到 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);
}
});
}
所以我正在制作一个应用程序,可以将安全消息发送到指定的 IP 地址。我正在使用 AES 来加密消息,那部分效果很好。我能够在发送消息之前加密消息并解密它。但是,当我尝试解密从服务器收到的消息时,我无法解密它。它以加密形式显示。
我收到此错误 "java.lang.NumberFormatException: Invalid 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);
}
};
我假设您以十六进制编码的形式发送密文。 DataInputStream#readUTF()
读取 single Unicode character from the stream。由于您要发送十六进制字符,这意味着可以从两个这样的 Unicode 字符构造一个密文字节。
问题在于 AES 对块进行运算。尝试分别解密每个 "half" 字节是行不通的。
您需要将解密方法重写为
- 使用流式解密或
- 读取整个密文,一口气解密
如果你想尝试流式解密,那么你基本上有两个选择:
- 使用
Cipher#update()
或 的偏移版本更新 Cipher 对象的内部缓冲区
- 使用
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;
我在不使用 CipherInputStream
的情况下找到了解决问题的方法。
每当我加密一条消息并发送它时,encryption/decryption 算法不会解密从服务器收到的消息。由于输出的加密消息与我发送的消息相同,我将传入的加密消息打印到 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);
}
});
}