RSA 加密:将代码从 js 移至 C#

发布于 2024-07-09 09:00:07 字数 2075 浏览 5 评论 0原文

我正在开发一个登录 teamcity 的用户代理,并且我正在尝试将密码加密从 js 转移到 c#。

这是 javascript

名为 rsa.js 和 encrypt.js 的部分很重要。 他们使用指数看起来像一个十六进制数 x10001 进行函数调用,

rsa.setPublic(publicKey,"10001");

据我所知,它是 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.

谢谢你,任何帮助都会使这成为一个非常快乐的圣诞节

编辑:看起来我的测试有缺陷,因为每次播种时间都会生成不同的加密密码

答案:我打开了访客访问,这绕过了这个问题,但我仍然想解决它

I'm working on an useragent that logs into teamcity and I'm trying to move the password encryption from js to c#.

this is the javascript

the section called rsa.js and encrypt.js are important. They make a function call with

rsa.setPublic(publicKey,"10001");

The exponent looks like its a hex number x10001 which is 65537 base10 as far as I can tell

here is teamcity's demo site

Note the account below does not belong to teamcity's demo site

This test validates if the encrypted text is equal to the clear text being encrypted with the public key.

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

so far the implementation looks like

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

but this complains with

System.Security.Cryptography.CryptographicException
Message: Input string does not contain a valid encoding of the 'RSA' 'Modulus' parameter.

Thank you any help will make this a very merry christmas

Edit: looks like my test is flawed since a different encryptedPassword is generated with each seeded time

Answer: I turned on guest access, that bypasses this problem, but I'd still like to solve it

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随波逐流 2024-07-16 09:00:07

由于加密使用 PKCS#1 随机填充,因此生成的“加密密码”必须始终不同。
这里的关键字是“随机填充”;-)

Since the encryption uses PKCS#1 random padding, the resulting "encryptedPassword" must always be different.
The keyword here is "random padding" ;-)

不再见 2024-07-16 09:00:07

您的 RSAKeyValue XML 格式错误,正确的格式在这里
http://www.w3.org/TR/xmldsig-core/# sec-RSAKeyValue

你的函数可能应该看起来像(假设 public_key 和指数是八位字节字符串...)

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

我希望有帮助,我还没有测试过。 我今天回家时会的。

You RSAKeyValue XML is malformed, the correct format is here
http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue

your function should probably look like (assuming that public_key and exponent are octet strings...)

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

In your case your exponent is 10001.

since in your case it looks like you do not have octet strings

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

I hope that helps, I haven't tested it yet. i will when i get home today.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文