【问题标题】:RSA Encryption : moving code from js to C#RSA 加密:将代码从 js 移动到 C#
【发布时间】:2008-12-02 15:10:07
【问题描述】:

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

this is the javascript

名为 rsa.js 和 encrypt.js 的部分很重要。他们使用

进行函数调用
rsa.setPublic(publicKey,"10001");

指数看起来像是一个十六进制数 x10001,据我所知是 65537 base10

here is teamcity's demo site

注意下面的账号不属于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

回答:我开启了访客访问,绕过了这个问题,但我还是想解决它

【问题讨论】:

    标签: c# javascript teamcity rsa


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 好的,这可以编译,一旦结果转换为十六进制,它就与我使用的指数不匹配。他们使用 x10001,即 65537 base10,但这并没有给出预期的结果。编码文本的长度与预期的长度大致相同
      猜你喜欢
      • 2012-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2019-05-19
      • 1970-01-01
      • 2013-08-20
      相关资源
      最近更新 更多