将消息发送到IP地址后进行AES解密

时间:2015-05-29 15:15:23

标签: java encryption aes datainputstream

所以我正在创建一个将安全消息发送到指定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);
        }

    };

2 个答案:

答案 0 :(得分:1)

我假设你以十六进制编码的形式发送密文。 DataInputStream#readUTF()读取single Unicode character from the stream。由于您正在发送十六进制字符,这意味着可以从两个这样的Unicode字符构造单个密文字节。

问题在于AES在块上运行。试图解密每一个单独的&#34; -byte分别无法工作。

您需要将解密方法重写为

  • 使用流解密或
  • 读取整个密文并一次解密。

如果您想尝试流式解密,那么您基本上有两种选择:

这是一个(伪代码)示例,在尝试解密之前读取整个内容:

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);
                    }
                });
            }