简体   繁体   中英

The password scrambling algorithm in NX client in c#

I'm currently trying to port the password scrambling algorithm of NX from QT-C++ to C#.

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

My current Code:

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

}
}

It's generates a string from the given password and I add it to the XML-Config file of the nxclient:

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

But the NXClient keeps saying "Authentication failed". So I'm quite sure there must be a mistake in my C#-Port of the C++ code. Especially I'm not sure about this line of the original code: sRet.ref(i1) = validCharList[i];

I have no idea what ref(i1) is doing.

Would be nice if someone discovers my mistake :)

Thanks in advance

The upper code part of scrambleString() does initialize and work on sRet , and the lower part on retStr which at last is returned making the work on sRet not used at all. You should probably combine retStr / sRet , maybe just use one string...

sRet.ref(i1) = validCharList[i]

The above code is just a simple char assignment, replacing char at pos i1 in sRet with char from string validCharList at pos i .

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