2

I have my c# server and my java client, their communication is encrypted but when the client sends an encrypted query, the server cant decrypt it, well it can but its totally unreadable, its like converting a byte array to a string, totally unreadable, this is the encryption on the clients side:

public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
    byte[] encryptedBytes = null;
    byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
    final Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
    final byte[] keyData = Arrays.copyOf(passwordBytes, KEY_SIZE
            / Byte.SIZE);
    final byte[] ivBytes = Arrays.copyOf(keyData, cipher.getBlockSize());
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyData, "AES"),
            new IvParameterSpec(ivBytes));
    encryptedBytes = cipher.doFinal(bytesToBeEncrypted);
    return encryptedBytes;
}

And the decryption on the server side:

internal string DecryptText(string inputString, Key k)
{
    try
    {
        inputString = inputString.Replace("\0", "");
        byte[] decryptedBytes = null;
        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
        byte[] bytesToBeDecrypted = Convert.FromBase64String(inputString);
        byte[] passwordBytes = Encoding.UTF8.GetBytes("azaz");
        passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
        using (MemoryStream ms = new MemoryStream())
        {
            using (RijndaelManaged AES = new RijndaelManaged())
            {
                AES.KeySize = 256;
                AES.BlockSize = 128;

                var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                AES.Key = key.GetBytes(AES.KeySize / 8);
                AES.IV = key.GetBytes(AES.BlockSize / 8);
                AES.Padding = PaddingMode.None;
                AES.Mode = CipherMode.CBC;

                using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                    cs.Close();
                }
                decryptedBytes = ms.ToArray();
            }
        }
        return Encoding.UTF8.GetString(decryptedBytes);
    }
    catch (Exception ex)
    {
        throw new SystemException(ex.Message);
    }
}

Thanks in advance

EDIT On the java client, this function call the AES_Encrypt function:

public String EncryptText(String input) throws NoSuchAlgorithmException
{
    byte[] bytesToBeEncrypted = input.getBytes();
    byte[] passwordBytes = Config.ServerKey.getBytes();
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    passwordBytes = md.digest(passwordBytes);
    byte[] bytesEncrypted = null;
try {
    bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
} catch (NoSuchPaddingException ex) {
    Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidAlgorithmParameterException ex) {
    Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
    Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
    Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
    Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
}
    return Base64.getEncoder().encodeToString(bytesEncrypted);
}

EDIT Implemented basic SslStream and verification server side

    private void Do()
    {
        int requestCount = 0;
        string serverResponse = null;
        string rCount = null;
        string dataFromClient = null;
        Byte[] sendBytes = null;
        requestCount = 0;
        Responder.Responder R = new Responder.Responder();
        while ((true))
        {
            try
            {
                byte[] buffer = new byte[4];
                requestCount = requestCount + 1;
                bool leaveInnerStreamOpen = true;
                RemoteCertificateValidationCallback validationCallback =
                  new RemoteCertificateValidationCallback(ClientValidationCallback);
                LocalCertificateSelectionCallback selectionCallback =
                  new LocalCertificateSelectionCallback(ServerCertificateSelectionCallback);
                EncryptionPolicy encryptionPolicy = EncryptionPolicy.AllowNoEncryption;
                _sslStream = new SslStream(clientSocket.GetStream(),
                  leaveInnerStreamOpen, validationCallback, selectionCallback, encryptionPolicy);
                X509Certificate2 certificate = ServerCertificate.Servercertificate(); //method that has access to the embedded certificate
                bool requireClientCertificate = true;
                SslProtocols enabledSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12;
                bool checkCertificateRevocation = true;
                _sslStream.AuthenticateAsServer
                  (certificate, requireClientCertificate, enabledSslProtocols, checkCertificateRevocation);
                buffer = new byte[4];
                int readBytes = _sslStream.Read(buffer, 0, 4);
                if (readBytes == 0)
                    break;
                int MessageSize = BitConverter.ToInt32(buffer, 0);
                byte[] bufferreader = new byte[MessageSize];
                clientSocket.ReceiveBufferSize = MessageSize;
                readBytes = _sslStream.Read(bufferreader, 0, MessageSize);
                Console.WriteLine(Convert.ToString(MessageSize));
                rCount = Convert.ToString(requestCount);
                dataFromClient = Encoding.ASCII.GetString(bufferreader);
                byte[] outbuffer = new byte[4];
                serverResponse = R.Respond(dataFromClient, K, clientSocket);
                sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                outbuffer = new byte[4];
                outbuffer = BitConverter.GetBytes(sendBytes.Length);
                _sslStream.Write(outbuffer, 0, 4);
                _sslStream.Flush();
                clientSocket.SendBufferSize = sendBytes.Length;
                MessageBox.Show(serverResponse);
                _sslStream.Write(sendBytes, 0, sendBytes.Length);
                _sslStream.Flush();
            }
            catch (Exception ex)
            {
                EndPointHandler.RemoveEndPoint(clientSocket);
                clientSocket.Close();
                Console.WriteLine("User Server >> " + ex.ToString());
                Thread.CurrentThread.Abort();
            }
        }
        EndPointHandler.RemoveEndPoint(clientSocket);
        Console.WriteLine("User Server >> " + "Client No:" + Convert.ToString(clNo) + " Stopped!");
    }

    private bool ClientValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        switch (sslPolicyErrors)
        {
            case SslPolicyErrors.RemoteCertificateNameMismatch:
                Console.WriteLine("Client's name mismatch. End communication ...\n");
                return false;
            case SslPolicyErrors.RemoteCertificateNotAvailable:
                Console.WriteLine("Client's certificate not available. End communication ...\n");
                return false;
            case SslPolicyErrors.RemoteCertificateChainErrors:
                Console.WriteLine("Client's certificate validation failed. End communication ...\n");
                return false;
        }
        Console.WriteLine("Client's authentication succeeded ...\n");
        return true;
    }

    private X509Certificate ServerCertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers)
    {
        return ServerCertificate.Servercertificate();
    }
3
  • Can you decrypt your data on the java side? Commented Nov 22, 2016 at 18:14
  • @StephenReindl Yes, without a problem Commented Nov 22, 2016 at 18:15
  • 1
    Your passwordBytes variable contains the key and the IV? That won't be causing your problem but you should change that ASAP. The IV should be randomly generated for each encryption. Commented Nov 22, 2016 at 21:19

1 Answer 1

2

In your Java code you have:

final Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);

Which likely means you are using PKCS5/7 Padding, unless you are just really terrible at picking names for your constants.

However, in your C# code, you have:

AES.Padding = PaddingMode.None;

Which is clearly not PKCS5/7 Padding... So you should probably change that to PaddingMode.PKCS7.

EDIT: Please also don't disregard my comment about your IV. If you want your code to actually be worth using, you should automatically generate the IV for each encryption and prepend it to the ciphertext.

Also just noticed that you derive your key data in different ways. You are using PBKDF2 w/ SHA1 in C# (Rfc2898DeriveBytes) but using a single iteration of SHA256 in Java. You'll need to pick one or another.

Sign up to request clarification or add additional context in comments.

4 Comments

Damn how could I look over that, thanks, but now the server throws: padding is invalid and cannot be removed... And about the comment, I really appreciate it :)
Okay thanks :), but my cryptography really sucks, i removed var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); and just used the passwordBytes for key and iv, but it still throws the same exception :(
@MatthiasHoste Yeah if you feel like you are out of your depth then you should probably scrap this and just use TLS.
So if I just use tls? Like in C# SslStream then I dont really have the need of using this encryption? Cool, wanted to use them both but I guess just using tls will do the same thing :D Thanks for the help and the advice,I really appreciate it :D EDIT will keep updating my question, it might also help others out then

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.