c#中NX客户端的密码加扰算法

时间:2012-09-16 12:52:15

标签: c# c++ windows nomachine-nx

我目前正在尝试从QT-C ++中移植NX的密码加扰算法 到C#。

来源: http://www.nomachine.com/ar/view.php?ar_id=AR01C00125

我目前的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace mynamespace
{
class NxScramble
{
    string ToScramble = "";
    int numValidCharList = 85;
    String dummyString = "{{{{";

    char[] validCharList = new char[]
    {
      '!',  '#',  '$',  '%',  '&',  '(', ')',  '*',  '+',  '-',
      '.',  '0',   '1',  '2',   '3',  '4',  '5',  '6', '7', '8',
      '9', ':',  ';',  '<',  '>',  '?',  '@',  'A',  'B', 'C',
      'D',  'E',  'F',  'G',  'H',  'I',  'J',  'K',  'L', 'M',
      'N', 'O',  'P',  'Q',  'R',  'S',  'T', 'U', 'V', 'W',
      'X',  'Y',  'Z',  '[', ']',  '_',  'a',  'b',  'c',  'd',
      'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',
      'o',  'p',  'q',  'r',  's',  't',  'u',  'v',  'w',  'x',
      'y',  'z',  '{',  '|',  '}'
    };

    public NxScramble(string s)
    {
        ToScramble = s;
    }

    public string scrambleString()
    {
        string sRet = "";

        if (ToScramble == null || ToScramble.Equals(""))
        {
            return ToScramble;
        }

        string str = encodePassword(ToScramble);

        if (str.Length < 32)
        {
            str += dummyString;
        }

        for (int iR = (str.Length - 1); iR >= 0; iR--)
        {
            //
            // Reverse string
            //
            sRet += str.ElementAt(iR);
        }

        if (sRet.Length < 32)
        {
            sRet += dummyString;
        }

        int k = getRandomValidCharFromList();
        int l = k + sRet.Length - 2;

        sRet.Insert(0, k.ToString());

        string retStr = "";

        for (int i1 = 1; i1 < sRet.Length; i1++)
        {
            int j = findCharInList(sRet.ElementAt(i1));

            if (j == -1)
            {
                return ToScramble;
            }
            int i = (j + l * (i1 + 1)) % validCharList.Length;
            /*
             * sRet.ref(i1) = validCharList[i];
             */
            retStr += validCharList[i];
        }

        char c = (char)(getRandomValidCharFromList() + 2);
        sRet += c;

        retStr = retStr.Replace("&", @"&amp;");
        retStr = retStr.Replace("\"", @"&quot;");
        retStr = retStr.Replace("'", @"&apos;");
        retStr = retStr.Replace("<", @"&lt;");
        retStr = retStr.Replace(">", @"&gt;");

        return retStr;
    }

    private string encodePassword(string p)
    {
        string sPass = ":";
        string sTmp = "";

        if (p.Equals(""))
        {
            return "";
        }

        for (int i = 0; i < p.Length; i++)
        {
            char c = (char)p.ElementAt(i);
            sTmp = String.Format("{0:d}:", (c + i + 1));
            sPass += sTmp;
            sTmp = "";
        }

        return sPass;
    }

    private int findCharInList(char c)
    {
        int i = -1;

        for (int j = 0; j < numValidCharList; j++)
        {
            if (validCharList[j] == c)
            {
                i = j;
                return i;
            }
        }
        return i;
    }

    private char getRandomValidCharFromList()
    {
        int k = DateTime.Now.Second;
        return validCharList[k];
    }

}
}

它从给定的密码生成一个字符串,然后将其添加到 nxclient的XML-Config文件:

        NxScramble nxs = new NxScramble(passPhrase);
        string ScambledPass = nxs.scrambleString();

        string nxconfig = @"
        ....
        ....
        <group name='Login' >
        <option key='Auth' value='"+ ScambledPass + @"' />
        <option key='Guest Mode' value='false' />
        <option key='Guest password' value='' />
        <option key='Guest username' value='' />
        <option key='Login Method' value='nx' />
        <option key='Public Key' value='
        .........
        .........
        ' />
        <option key='User' value='" + username + @"' />
        </group>
        ";

但NXClient一直说“身份验证失败”。所以我很确定 我的C#-Port中的C ++代码一定有错误。 特别是我不确定原始代码的这一行:             sRet.ref(i1)= validCharList [i];

我不知道ref(i1)正在做什么。

如果有人发现我的错误会很好:)

提前致谢

1 个答案:

答案 0 :(得分:0)

scrambleString()的高级代码部分会初始化并处理sRet, 以及retStr的下半部分,最后返回进行处理 完全没有使用sRet。您应该将retStr / sRet合并,也许只是 使用一个字符串...

sRet.ref(i1) = validCharList[i]

上面的代码只是一个简单的char赋值,替换了pos中的char i1 sRet validCharList来自i位置{{1}}的字符串。