2011-10-21 177 views
1

我正在尝试编写C#应用程序,它可以在另一个盒子上远程更改RealVNC密码。编码/解码RealVNC密码

目前有效的是,我可以从已更改的方框中提取密码,将其存储为十六进制字符串,然后将其发送到另一个方框,然后更改密码,但需要能够更改密码或随时随地进行。

我在创建放置在注册表中的正确二进制文件时遇到问题。

我知道VNC键:

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

因此,使用上述按键与通过“1234”作为密码使用下面的代码进行加密:

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; 
    } 

通过返回的字节数组后到BitConverter.ToString,我希望获得与注册表中存储的相同的十六进制值,该密码已经用RealVNC本身设置为1234,但我不是。

+0

运气好吗?我已经看过了vncpwdump src代码,显然在使用之前对密钥做了一些处理。我正在试图通过openssl重现加密,但到目前为止它没有结果。 – olivervbk

+1

似乎DES使用密码反向位排序来加密... [链接](http://www.vidarholen.net/contents/junk/vnc.html) 虽然没有测试过。 – olivervbk

回答

0

这里有我的消息来源加密/解密的VNC密码:

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(); 
    } 

并且解密:

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); 
    } 

同样需要这样的功能:

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; 
    } 

在顶部添加:

using System.Security.Cryptography; 

不记得我从哪里得到的代码。我不是原作者。