Я работаю над пользовательским агентом, который входит в teamcity, и я пытаюсь перенести шифрование пароля с js на C#.
важны разделы под названием rsa.js и encrypt.js. Они вызывают функцию с помощью
rsa.setPublic(publicKey,"10001");
Показатель выглядит как шестнадцатеричное число x10001, которое, насколько я могу судить, составляет 65537 base10.
вот демонстрационный сайт teamcity
Обратите внимание, что учетная запись ниже не принадлежит демонстрационному сайту teamcity.
Этот тест проверяет, совпадает ли зашифрованный текст с открытым текстом, зашифрованным с помощью открытого ключа.
[Test]
public void should_be_able_to_encode_a_string() {
string public_key = "00b46e5cd2f8671ebf2705fd9553137da082b2dd3dbfa06f254cdfeb260fb21bc2c37a882de2924d7dd4c61eb81368216dfea7df718488b000afe7120f3bbbe5b276ac7f2dd52bd28445a9be065bd19dab1f177e0acc035be4c6ccd623c1de7724356f9d6e0b703d01583ebc4467d8454a97928b5c6d0ba3f09f2f8131cc7095d9";
string expected = "1ae1d5b745776f72172b5753665f5df65fc4baec5dd4ea17d43e11d07f10425b3e3164b0c2ba611c72559dc2b00149f4ff5a9649b1d050ca6a5e2ec5d96b787212874ab5790922528a9d7523ab4fe3a002e8f3b66cab6e935ad900805cf1a98dc6fcb5293c7f808917fd9015ba3fea1d59e533f2bdd10471732cccd87eda71b1";
string data = "scott.cowan";
string actual = new EncryptionHelper().Encrypt(public_key, data);
Assert.AreEqual(expected,actual);
}
пока реализация выглядит как
public string Encrypt(string public_key, string data)
{
rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(String.Format("<RSAKeyValue>{0}</RSAKeyValue>",public_key));
byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data);
byte[] cipherbytes = rsa.Encrypt(plainbytes,false);
return Convert.ToBase64String(cipherbytes);
}
но это жалуется на
System.Security.Cryptography.CryptographicException
Message: Input string does not contain a valid encoding of the 'RSA' 'Modulus' parameter.
Спасибо, любая помощь сделает это Рождество очень счастливым
Обновлено: похоже, что мой тест ошибочен, поскольку с каждым разом создается другой encryptedPassword
Ответ: Я включил гостевой доступ, что позволяет обойти эту проблему, но все равно хочу ее решить.





Вы RSAKeyValue XML искажены, правильный формат здесь http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
ваша функция, вероятно, должна выглядеть так (при условии, что public_key и exponent являются строками октетов ...)
public string Encrypt(string public_key,string exponent, string data)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(String.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",public_key,exponent));
byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data);
byte[] cipherbytes = rsa.Encrypt(plainbytes,false);
return Convert.ToBase64String(cipherbytes);
}
В вашем случае показатель 10001.
поскольку в вашем случае похоже, что у вас нет строк октетов
public string Encrypt(string public_keyHex,uint exp,string data)
{
byte[] bytes = new byte[public_keyHex.Length / 2];
for (int i = 0; i < public_keyHex.Length-1; i+=2)
{
bytes[i / 2] = byte.Parse(public_keyHex.Substring(i, 2),System.Globalization.NumberStyles.HexNumber);
}
string public_key=Convert.ToBase64String(bytes);
return Encrypt(public_key,Convert.ToBase64String(BitConverter.GetBytes(exp)),data);
}
Надеюсь, это поможет, я еще не тестировал. Я буду, когда вернусь домой сегодня.
Поскольку шифрование использует случайное заполнение PKCS # 1, результирующий "encryptedPassword" должен всегда будет другим. Ключевое слово здесь - "случайное заполнение" ;-)
хорошо, это компилируется, как только результат преобразован в шестнадцатеричный, он не соответствует показателям, которые я использовал. Они используют x10001, что составляет 65537 base10, но это не дает ожидаемого результата. закодированный текст примерно такой же длины, как и предполагаемый