2010-07-08 5 views
4

J'ai un gros problème. I en utilisant cette fonction C# pour coder mon message:Résultat différent SHA1 Hash entre Java et C#

byte[] buffer = Encoding.ASCII.GetBytes(file_or_text); 
SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider(); 
String hashText = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", ""); 

Côté java, j'utiliser cet extrait:

MessageDigest md = MessageDigest.getInstance("SHA-1"); 
byte[] sha1hash = new byte[40]; 
md.update(text.getBytes("iso-8859-1"), 0, text.length()); 
sha1hash = md.digest(); 

Mon message est: Bloc | Notes | Texte £ $% &/(?) =^€> < {} § C °;:. _- @ # ùàòè +

Je ce résultat:

(C#) 8EDC7F756BCECDB99B045FA3DEA2E36AA0BF0875 
(Java) 2a566428826539365bb2fe2197da91395c2b1b72 

Pouvez-vous m'aider s'il vous plaît ?? Merci ...

+1

Pourquoi vous utilisez l'encodage iso-8859-1 dans l'extrait Java et non pas sur l'extrait C#? – Lazarus

+1

Quels sont les tableaux d'octets avant de calculer les hachages? Ils peuvent ne pas être les mêmes (peut-être parce que vous utilisez l'encodage ASCII et ISO-8850-1) – Progman

+0

Jetez un oeil à http://stackoverflow.com/questions/4819794/sha1-c-sharp-equivalent-of-this-java – Koekiebox

Répondre

4

Ma conjecture est que vous semblez comparer des octets ASCII à Latin1 octets. Essayez de changer

md.update(text.getBytes("iso-8859-1"), 0, text.length()); 

à cette

md.update(text.getBytes("ISO646-US"), 0, text.length()); 

Cela pourrait résoudre votre problème.

(ou commutateur C# pour utiliser Latin1)

Qu'est-ce qui se passe dans votre programme de votre méthode GetBytes retourne des valeurs différentes pour les mêmes caractères en fonction de l'encodage, notre nifty algorithme de hachage SHA1 est obtenir adopté différents paramètres entraînant différentes valeurs de retour.

+0

Puis-je changer le code du côté C#? Du côté java c'est plus difficile pour moi ... (je ne peux pas toucher le côté Java) – CeccoCQ

+1

Jon Skeet l'explique sur son post. – Meiscooldude

+0

Merci, j'ai lu votre réponse. Tu es mon dieu C#! :) – CeccoCQ

4

Le changement à utiliser ISO-8859-1 sur le côté C# est facile:

byte[] buffer = Encoding.GetEncoding(28591).GetBytes(file_or_text); 

Cependant, à la fois ceci et ASCII perd des données si votre texte contient des caractères Unicode ci-dessus U + 00FF. Idéalement, si vos données source sont véritablement du texte, vous devriez utiliser un encodage qui va gérer n'importe quoi (par exemple UTF-8) et si vos données source sont réellement binaires, vous ne devriez pas du tout passer par le codage de texte.

0

Essayez le code suivant:

public static string Sha1encode(string toEncrypt) { 
    // Produce an array of bytes which is the SHA1 hash 
    byte[] sha1Signature = new byte[40]; 

    byte[] sha = System.Text.Encoding.Default.GetBytes(toEncrypt); 
    SHA1 sha1 = SHA1Managed.Create(); 
    sha1Signature = sha1.ComputeHash(sha); 

    // The BASE64 encoding standard's 6-bit alphabet, from RFC 1521, 
    // plus the padding character at the end. 

    char[] Base64Chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 
      'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 
      'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 
      'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 
      't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', 
      '5', '6', '7', '8', '9', '+', '/', '=' }; 
    // Algorithm to encode the SHA1 hash using Base64 
    StringBuilder sb = new StringBuilder(); 
    int len = sha1Signature.Length; 
    int i = 0; 
    int ival; 
    while (len >= 3) { 
     ival = ((int) sha1Signature[i++] + 256) & 0xff; 
     ival <<= 8; 
     ival += ((int) sha1Signature[i++] + 256) & 0xff; 
     ival <<= 8; 
     ival += ((int) sha1Signature[i++] + 256) & 0xff; 
     len -= 3; 
     sb.Append(Base64Chars[(ival >> 18) & 63]); 
     sb.Append(Base64Chars[(ival >> 12) & 63]); 
     sb.Append(Base64Chars[(ival >> 6) & 63]); 
     sb.Append(Base64Chars[ival & 63]); 
    } 
    switch (len) { 
    case 0: // No pads needed. 
     break; 
    case 1: // Two more output bytes and two pads. 
     ival = ((int) sha1Signature[i++] + 256) & 0xff; 
     ival <<= 16; 
     sb.Append(Base64Chars[(ival >> 18) & 63]); 
     sb.Append(Base64Chars[(ival >> 12) & 63]); 
     sb.Append(Base64Chars[64]); 
     sb.Append(Base64Chars[64]); 
     break; 
    case 2: // Three more output bytes and one pad. 
     ival = ((int) sha1Signature[i++] + 256) & 0xff; 
     ival <<= 8; 
     ival += ((int) sha1Signature[i] + 256) & 0xff; 
     ival <<= 8; 
     sb.Append(Base64Chars[(ival >> 18) & 63]); 
     sb.Append(Base64Chars[(ival >> 12) & 63]); 
     sb.Append(Base64Chars[(ival >> 6) & 63]); 
     sb.Append(Base64Chars[64]); 
     break; 
    } 

    string base64Sha1Signature = sb.ToString(); 
    return base64Sha1Signature; 
} 
+0

Pouvez-vous dire ce qu'il faisait pour faire la différence? –