简体   繁体   中英

Sending encrypted data via TCP (“Bad Data” exception)

How can i send illegal charecters from tpc client to tcp server. This is an example of what the encrypted gibberish looks like:

https://i.stack.imgur.com/wfZdm.png

How can i send this pice of gibberish to either my client or server?

This is my encryption & decryption code

public static string Decrypt(string data)
        {
            byte[] dataToDecrypt = StringToByteArray(data);

            byte[] decryptedData;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(privateKey);
                decryptedData = rsa.Decrypt(dataToDecrypt, false);
            }

            UnicodeEncoding byteConverter = new UnicodeEncoding();
            return ByteArrayToString(decryptedData);
        }

        public static string Encrypt(string data, string publicKey)
        {
            UnicodeEncoding byteConverter = new UnicodeEncoding();
            byte[] dataToEncrypt = StringToByteArray(data);

            byte[] encryptedData;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(publicKey);
                encryptedData = rsa.Encrypt(dataToEncrypt, false);
            }
            return ByteArrayToString(encryptedData);
        }


public static byte[] StringToByteArray(string data)
        {
            return Encoding.ASCII.GetBytes(data);
        }

        public static string ByteArrayToString(byte[] bytes)
        {
            return Encoding.ASCII.GetString(bytes);
        }

I have made it so the client and the server share eachothers public keys but i am getting Exception "Bad data". One more thing if i send encrypted data from a client to the server which data is 128 bytes the server receives only 78 bytes for example

There's a few things wrong with your code:

  • You shouldn't be using String at all.
    • String is meant for text, not arbitrary binary data (I assume you got this impression from C or PHP where their string types are really just synonyms for - or thin-wrappers over - a byte-array).
  • Keep the Byte[] buffer you get from rs.Encrypt and pass that directly to your Socket , TcpClient or NetworkStream that you're using. You'll need to define a binary protocol with length-prefix though.
  • Encoding.ASCII.GetBytes will convert the UTF-16LE-encoded characters in the String data instance to 7-bit ASCII, it does this by replacing characters with values above 0x7F with '?' - this is not what you want! (and this is what's causing the garbage output on your screen: those "illegal characters" are byte-values above 0x7F that are outside ASCII's 7-bit range. From the documentation:

    It uses replacement fallback to replace each string that it cannot encode and each byte that it cannot decode with a question mark ("?") character.

  • If you really do want to transmit data over the network using human-readable text then use Base64 encoding: Convert.ToBase64String( Byte[] buffer ) and convert it back using Convert.FromBase64String( String s ) at the receiving end - but you'll still need to length-prefix or delimit your data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM