2008-12-02 29 views
3

我正在研究一個登錄到teamcity的useragent,並且我試圖將密碼加密從js移動到c#。RSA加密:將代碼從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生成wi每個播種時間TH

答:我打開訪客訪問,繞過這個問題,但我還是想解決它

回答

3

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

我希望幫助,我沒有測試它。我會在我今天回家的時候。

+0

確定這個編譯,一旦結果轉換爲十六進制,它不匹配我正在使用的指數。他們使用x10001這是65537 base10,但沒有給出預期的結果。編碼的文本與預期的長度大致相同 – 2008-12-03 10:17:16

3

由於加密使用PKCS#1隨機填充,因此生成的「encryptedPassword」必須始終不同。 這裏的關鍵字是「隨機填充」;-)