В настоящее время я пытаюсь перенести алгоритм скремблирования паролей NX из QT-C ++
в 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("&", @"&");
retStr = retStr.Replace("\"", @""");
retStr = retStr.Replace("'", @"'");
retStr = retStr.Replace("<", @"<");
retStr = retStr.Replace(">", @">");
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];
}
}
}
Он генерирует строку из данного пароля, и я добавляю ее в
XML-файл конфигурации 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>
";
Но NXClient продолжает говорить «Проверка подлинности не удалась». Так что я уверен
должна быть ошибка в моем C # -порте кода C ++.
Особенно я не уверен насчет этой строки исходного кода:
sRet.ref (i1) = validCharList [i];
Я понятия не имею, что делает ref (i1).
Было бы неплохо, если бы кто-то обнаружил мою ошибку 🙂
заранее спасибо
Верхняя часть кода scrambleString()
инициализирует и работает на sRet
,
и нижняя часть на retStr
который, наконец, возвращается, делая работу на
sRet
не используется вообще. Вы, вероятно, должны объединить retStr
/sRet
может просто
использовать одну строку …
sRet.ref(i1) = validCharList[i]
Приведенный выше код является простым назначением символа, заменяя char в pos
i1
в sRet
с символом из строки validCharList
в поз i
,
Других решений пока нет …