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



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

我假设您以十六进制编码的形式发送密文。DataInputStream#readUTF()从流中读取单个Unicode字符。由于您发送的是十六进制字符,这将意味着可以由两个这样的Unicode字符构造单个密文字节。

问题是AES在块上操作。试图单独解密每个"半"字节是行不通的。

您需要将解密方法重写为

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

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

  • 使用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。每当我加密并发送消息时,加密/解密算法都不会解密从服务器接收到的消息。由于输出的加密消息与我发送的相同,因此我将传入的加密消息打印到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);
                    }
                });
            }

相关内容

  • 没有找到相关文章

最新更新