2010-05-28 88 views
1

我們被送到這個公式來加密用Java編寫的字符串:從Java轉換到C#:簡單的代碼來重新編碼字符串

String  myInput = "test1234"; 
MessageDigest  md = MessageDigest.getInstance("SHA"); 
byte[]   myD = md.digest(myInput.getBytes()); 
BASE64Encoder en64 = new BASE64Encoder(); 
String  myOutput = new String ( 
          Java.net.URLEncoder.encode(en64.encode(myD))); 
// myOutput becomes "F009U%2Bx99bVTGwS3cQdHf%2BJcpCo%3D" 

我們在C#寫這個嘗試:

System.Security.Cryptography.SHA1 sha1 = 
    new System.Security.Cryptography.SHA1CryptoServiceProvider(); 
string myOutput = HttpUtility.UrlEncode( 
         Convert.ToBase64String( 
          sha1.ComputeHash( 
           ASCIIEncoding.Default.GetBytes(myInput)))); 

但是輸出沒有接近相同的地方。它甚至沒有百分號。任何人都會知道我們要出錯的地方嗎?

回答

2

我建議你打破下來。

1-比較從Java String.getBytes()和.NET Encoding.GetBytes()返回的內容以下是一些.NET代碼,它將爲每個編碼轉儲字符串的字節,並將結果與那些來自Java。

string myInput = "test1234"; 
foreach (EncodingInfo ei in Encoding.GetEncodings()) 
{ 
    byte[] bytes = ei.GetEncoding().GetBytes(myInput); 
    Console.WriteLine("{0}\t\t{1}", 
    BitConverter.ToString(bytes), ei.DisplayName); 
} 

2-如果從步驟1找到正確的編碼,請轉到下一步。比較Java和.NET中相同字節的SHA1散列值。這應該是匹配的,但我喜歡有條不紊,並且從不很少做出假設,尤其是當他們快速且容易驗證時。

3-一旦你顯示你有相同的SHA1字節,你可以做Base64編碼和比較。

4-最後執行URL編碼,如果你走到這一步,我懷疑你會發現在外殼的不同。 IIRC .NET Url編碼使用小寫字母,並且從您的示例中我看到Java使用大寫字母,例如Java中的%3D可能是.NET中的%3d。

2

和LukeH一樣,如果您在同一臺計算機上同時運行Java版本和C#版本,則可以嘗試將C#版本中的編碼更改爲Encoding.Default.GetBytes(myInput)

如果失敗或不是一個選項,您可以嘗試打印字節值,並將它與Java中的各個步驟只是爲了找出錯誤所在:

String myInput = "test1234"; 
System.Security.Cryptography.SHA1 crypto = new System.Security.Cryptography.SHA1CryptoServiceProvider(); 
Byte[] myInputBytes = Encoding.Default.GetBytes(myInput); 
Console.WriteLine(BitConverter.ToString(myInputBytes)); 
Byte[] hash = crypto.ComputeHash(myInputBytes); 
Console.WriteLine(BitConverter.ToString(hash));