Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encode / Decode RealVNC password

Tags:

c#

.net-2.0

des

I'm trying to write C# application that can remotely change the RealVNC password on another box.

What works currently is that I can pull a password from a box that has already been changed, store it as a hex string, and then send it to another box AND then change the password that way but I need to be able to change the password or randomize it on the fly.

I'm having problems with creating the correct binary to place in the registry.

I know the VNC key:

byte[] Key = { 23, 82, 107, 6, 35, 78, 88, 7 };

So using the above key and passing "1234" as the password to encrypt using the following code:

public static byte[] EncryptTextToMemory(string Data, byte[] Key)
{
    try
    {
        MemoryStream mStream = new MemoryStream()

        DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider();
        desProvider.Mode = CipherMode.ECB;
        desProvider.Key = Key;

        CryptoStream cStream = new CryptoStream(mStream,
            desProvider.CreateEncryptor(),
            CryptoStreamMode.Write);

        byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data);

        cStream.Write(toEncrypt, 0, toEncrypt.Length);
        cStream.FlushFinalBlock();

        byte[] ret = mStream.ToArray();

        cStream.Close();
        mStream.Close();

        return ret;
    }
    catch (CryptographicException ex)
    {
        MessageBox.Show("A Cryptographic error occurred: " + ex.Message);
        return null;
    }

After passing the returned byte array to BitConverter.ToString, I would expect to get the same hex values as stored in the registry of a password already set to 1234 with RealVNC itself, but I'm not.

like image 982
DrkNite72 Avatar asked Oct 28 '25 00:10

DrkNite72


1 Answers

Here are my sources to encrypt/decrypt VNC password:

public static string EncryptVNC(string password)
    {
        if (password.Length > 8)
        {
            password = password.Substring(0, 8);
        }
        if (password.Length < 8)
        {
            password = password.PadRight(8, '\0');
        }

        byte[] key = { 23, 82, 107, 6, 35, 78, 88, 7 };
        byte[] passArr = new ASCIIEncoding().GetBytes(password);
        byte[] response = new byte[passArr.Length];
        char[] chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

        // reverse the byte order
        byte[] newkey = new byte[8];
        for (int i = 0; i < 8; i++)
        {
            // revert desKey[i]:
            newkey[i] = (byte)(
                ((key[i] & 0x01) << 7) |
                ((key[i] & 0x02) << 5) |
                ((key[i] & 0x04) << 3) |
                ((key[i] & 0x08) << 1) |
                ((key[i] & 0x10) >> 1) |
                ((key[i] & 0x20) >> 3) |
                ((key[i] & 0x40) >> 5) |
                ((key[i] & 0x80) >> 7)
                );
        }
        key = newkey;
        // reverse the byte order

        DES des = new DESCryptoServiceProvider();
        des.Padding = PaddingMode.None;
        des.Mode = CipherMode.ECB;

        ICryptoTransform enc = des.CreateEncryptor(key, null);
        enc.TransformBlock(passArr, 0, passArr.Length, response, 0);

        string hexString = String.Empty;
        for (int i = 0; i < response.Length; i++)
        {
            hexString += chars[response[i] >> 4];
            hexString += chars[response[i] & 0xf];
        }
        return hexString.Trim().ToLower();
    }

And to decrypt:

public static string DecryptVNC(string password)
    {
        if (password.Length < 16)
        {
            return string.Empty;
        }

        byte[] key = { 23, 82, 107, 6, 35, 78, 88, 7 };
        byte[] passArr = ToByteArray(password);
        byte[] response = new byte[passArr.Length];

        // reverse the byte order
        byte[] newkey = new byte[8];
        for (int i = 0; i < 8; i++)
        {
            // revert key[i]:
            newkey[i] = (byte)(
                ((key[i] & 0x01) << 7) |
                ((key[i] & 0x02) << 5) |
                ((key[i] & 0x04) << 3) |
                ((key[i] & 0x08) << 1) |
                ((key[i] & 0x10) >> 1) |
                ((key[i] & 0x20) >> 3) |
                ((key[i] & 0x40) >> 5) |
                ((key[i] & 0x80) >> 7)
                );
        }
        key = newkey;
        // reverse the byte order

        DES des = new DESCryptoServiceProvider();
        des.Padding = PaddingMode.None;
        des.Mode = CipherMode.ECB;

        ICryptoTransform dec = des.CreateDecryptor(key, null);
        dec.TransformBlock(passArr, 0, passArr.Length, response, 0);

        return System.Text.ASCIIEncoding.ASCII.GetString(response);
    }

Also this function is needed:

public static byte[] ToByteArray(String HexString)
    {
        int NumberChars = HexString.Length;
        byte[] bytes = new byte[NumberChars / 2];

        for (int i = 0; i < NumberChars; i += 2)
        {
            bytes[i / 2] = Convert.ToByte(HexString.Substring(i, 2), 16);
        }

        return bytes;
    }

At top add:

using System.Security.Cryptography;

Can't remember where I got the code from. I am not the original author.

like image 159
Andrej K. Avatar answered Oct 29 '25 14:10

Andrej K.