UDP java套接字编程,收到数据后就变成了怪异的字符

时间:2017-11-07 07:36:04

标签: java sockets encryption cryptography udp

我通过RC4密码传递了一个字符串,它给了我“™á> *:¢ÞÒ>¥%”

此后,我使用此代码发送了它

DatagramPacket C1C2 = new DatagramPacket(RC4cipherData, RC4cipherData.length, IPAddress,9876 );
clientSocket.send(C1C2);

所以,一旦我使用此代码接收到主机/服务器端

socket.receive( packet );
test = packet.getData();
System.out.println(new String(test));

我得到了这个 *: > ,我尝试使用RC4解密但失败了,但使用上面的密文我能够取回我的纯文本。

如果你们需要

,还有其他数据
 byte[] RC4cipherData = rc4.encryptMessage(RC4ptext, RK.toString());

有人能解释是什么导致密文变成那些奇怪的字符吗?

RC4代码

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * Implementation of RC4 stream cipher
 *
 * @author Iurii Sergiichuk
 */
public class RC4 {
    private static final int SBOX_LENGTH = 256;
    private static final int KEY_MIN_LENGTH = 5;
    /**
     * Key array
     */
    private byte[] key = new byte[SBOX_LENGTH - 1];
    /**
     * Sbox
     */
    private int[] sbox = new int[SBOX_LENGTH];

    public RC4() {
        reset();
    }

    public RC4(String key) throws InvalidKeyException {
        this();
        setKey(key);
    }

    private void reset() {
        Arrays.fill(key, (byte) 0);
        Arrays.fill(sbox, 0);
    }

    /**
     * Encrypt given message String with given Charset and key
     *
     * @param message message to be encrypted
     * @param charset charset of message
     * @param key     key
     * @return encrypted message
     * @throws InvalidKeyException if key length is smaller than 5 or bigger than 255
     */
    public byte[] encryptMessage(String message, Charset charset, String key)
            throws InvalidKeyException {
        reset();
        setKey(key);
        byte[] crypt = crypt(message.getBytes());
        reset();
        return crypt;
    }

    /**
     * Encrypt given message String with given Key and pre-defined UTF-8 charset
     *
     * @param message message to be encrypted
     * @param key     key
     * @return encrypted message
     * @throws InvalidKeyException if key length is smaller than 5 or bigger than 255
     * @see StandardCharsets
     */
    public byte[] encryptMessage(String message, String key)
            throws InvalidKeyException {
        return encryptMessage(message, StandardCharsets.UTF_8, key);
    }

    /**
     * Decrypt given byte[] message array with given charset and key
     *
     * @param message message to be decrypted
     * @param charset charset of message
     * @param key     key
     * @return string in given charset
     * @throws InvalidKeyException if key length is smaller than 5 or bigger than 255
     */
    public String decryptMessage(byte[] message, Charset charset, String key)
            throws InvalidKeyException {
        reset();
        setKey(key);
        byte[] msg = crypt(message);
        reset();
        return new String(msg);
    }

    /**
     * Decrypt given byte[] message array with given key and pre-defined UTF-8
     * charset
     *
     * @param message message to be decrypted
     * @param key     key
     * @return string in given charset
     * @throws InvalidKeyException if key length is smaller than 5 or bigger than 255
     * @see StandardCharsets
     */
    public String decryptMessage(byte[] message, String key)
            throws InvalidKeyException {
        return decryptMessage(message, StandardCharsets.UTF_8, key);
    }

    /**
     * Crypt given byte array. Be aware, that you must init key, before using
     * crypt.
     *
     * @param msg array to be crypt
     * @return crypted byte array
     * @see <a href="http://en.wikipedia.org/wiki/RC4#Pseudo-random_generation_algorithm_.28PRGA.29">Pseudo-random generation algorithm</a>
     */
    public byte[] crypt(final byte[] msg) {
        sbox = initSBox(key);
        byte[] code = new byte[msg.length];
        int i = 0;
        int j = 0;
        for (int n = 0; n < msg.length; n++) {
            i = (i + 1) % SBOX_LENGTH;
            j = (j + sbox[i]) % SBOX_LENGTH;
            swap(i, j, sbox);
            int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LENGTH];
            code[n] = (byte) (rand ^ msg[n]);
        }
        return code;
    }

    /**
     * Initialize SBOX with given key. Key-scheduling algorithm
     *
     * @param key key
     * @return sbox int array
     * @see <a href="http://en.wikipedia.org/wiki/RC4#Key-scheduling_algorithm_.28KSA.29">Wikipedia. Init sbox</a>
     */
    private int[] initSBox(byte[] key) {
        int[] sbox = new int[SBOX_LENGTH];
        int j = 0;

        for (int i = 0; i < SBOX_LENGTH; i++) {
            sbox[i] = i;
        }

        for (int i = 0; i < SBOX_LENGTH; i++) {
            j = (j + sbox[i] + (key[i % key.length]) & 0xFF) % SBOX_LENGTH;
            swap(i, j, sbox);
        }
        return sbox;
    }

    private void swap(int i, int j, int[] sbox) {
        int temp = sbox[i];
        sbox[i] = sbox[j];
        sbox[j] = temp;
    }

    /**
     * Setup key
     *
     * @param key key to be setup
     * @throws InvalidKeyException if key length is smaller than 5 or bigger than 255
     */
    public void setKey(String key) throws InvalidKeyException {
        if (!(key.length() >= KEY_MIN_LENGTH && key.length() < SBOX_LENGTH)) {
            throw new InvalidKeyException("Key length has to be between "
                    + KEY_MIN_LENGTH + " and " + (SBOX_LENGTH - 1));
        }

        this.key = key.getBytes();
    }

}

/**
 * Exception made for recognise invalid keys
 *
 * @author Iurii Sergiichuk
 */
class InvalidKeyException extends RuntimeException {

    private static final long serialVersionUID = -2412232436238451574L;

    public InvalidKeyException(String message) {
        super(message);
    }

}

服务器代码

   socket.receive( packet );
             test = packet.getData();
            // test = new byte[packet.getlength()];
             System.out.println(new String(test));

客户代码

 byte[] RC4cipherData = rc4.encryptMessage(RC4ptext, RK.toString());
                System.out.println("encryption: " + new String(RC4cipherData));
                String RC4decryptData = rc4.decryptMessage(RC4cipherData, RK.toString());
                System.out.println("decryption: " + RC4decryptData);
                //time to send C1 and C2 encrypted to server/alice
                String C1C2PText = encryptedRK.toString() + "%" + new String(RC4cipherData) + "%";
                System.out.println("Test: " + C1C2PText);
                byte [] C1C2data = C1C2PText.getBytes();

                //System.out.println("Print conversion: " + C1C2data[0].);
               // DatagramPacket C1C2 = new DatagramPacket(C1C2data, C1C2data.length, IPAddress,9876 );
                DatagramPacket C1C2 = new DatagramPacket(RC4cipherData, RC4cipherData.length, IPAddress,9876 );
                clientSocket.send(C1C2);

1 个答案:

答案 0 :(得分:0)

  

有人能解释是什么导致密文变成那些奇怪的字符吗?

你做到了。密文,错误,奇怪的字符。尝试在打印前对其进行解密。执行此操作时,请确保仅使用每个数据报中的packet.getLength()个字节,这与您现在正在执行的操作不同。