2011-11-24 44 views
1

我有一個用於SHA-1哈希的.NET SOAP web服務(.asmx)以獲取Base64哈希字符串。即使在Android和.NET中輸入相同的字符串後,兩個不同的哈希值

這裏是我的web服務代碼:

public class Service1 : System.Web.Services.WebService 
    { 
    [WebMethod] 
    public string HashCode(string str) 
    { 
     string rethash = ""; 
     try 
     { 

      System.Security.Cryptography.SHA1 hash = System.Security.Cryptography.SHA1.Create(); 
      System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding(); 
      byte[] combined = encoder.GetBytes(str); 
      hash.ComputeHash(combined); 
      rethash = Convert.ToBase64String(hash.Hash); 
     } 
     catch (Exception ex) 
     { 
      string strerr = "Error in HashCode : " + ex.Message; 
     } 
     return rethash; 
    } 
} 

這裏哈希返回輸入字符串 「abc」 是

QZK + NkcGgWq6PiVxeFDCbJzQ2J0 =

現在,Android的代碼再次使用SHA-1和Base64是:

public class PaswordencodingActivity extends Activity 
    { 
private static final String soap_action = "http://tempuri.org/HashCode"; 
private static final String method_name = "HashCode"; 
private static final String namespace2 = "http://tempuri.org/"; 
private static final String url2 = "http://10.0.2.2/checkhash/Service1.asmx"; 

String password="abc"; 
public final static int NO_OPTIONS = 0; 
String hash; 
    String result2; 

    @Override 
     public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

    final EditText pass=(EditText)findViewById(R.id.editText1); 
    Button encode=(Button)findViewById(R.id.button1); 

    encode.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      // Perform action on click 
      password=pass.getText().toString(); 
      if(password!=null){ 
      try { 
    SHA1(password) ; 
      } catch (NoSuchAlgorithmException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } catch (UnsupportedEncodingException e) { 
    // TODO Auto-generated catch block           
       e.printStackTrace(); 
    } catch (IOException e) 
       { 
    // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
      } 
      else{ 
    Toast.makeText(PaswordencodingActivity.this, "this is a negative onClick", Toast.LENGTH_LONG).show(); 
      } 

     } 
    }); 

} 
private static String convertToHex(byte[] bytes) throws java.io.IOException 
{  
     StringBuffer sb = new StringBuffer(); 
     String hex=null; 
     for (int i = 0; i < bytes.length; i++) 
     {   
      hex=Base64.encodeToString(bytes, 0, bytes.length, NO_OPTIONS); 
      if (hex.length() == 1) 
      { 
       sb.append('0'); 
      } 
      sb.append(hex); 
     } 
     return sb.toString(); 
    } 


public void SHA1(String text) 
     throws NoSuchAlgorithmException, IOException 
    { 
     MessageDigest md; 
     md = MessageDigest.getInstance("SHA-1"); 
     byte[] sha1hash = new byte[40]; 
     md.update(text.getBytes("iso-8859-1"), 0, text.length()); 
     sha1hash = md.digest(); 
     hash=convertToHex(sha1hash); 
     System.out.println("hash value is"+hash); 
    try 
    { 
     result2 = call3(hash); 
} catch (XmlPullParserException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

if(result2.equalsIgnoreCase(hash)) 
{ 
    System.out.println("success"); 

} 

} 

public String call3(String hash) throws XmlPullParserException 
    { 
     String b="";  
     SoapObject request = new SoapObject(namespace2, method_name);      
     request.addProperty("str",hash); 
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
    envelope.dotNet = true; 
    envelope.setOutputSoapObject(request); 

    HttpTransportSE android = new HttpTransportSE(url2); 
     android.debug = true; 
    try 
{ 

     android.call(soap_action, envelope); 
     SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); 
     Log.i("myapp",result.toString()); 
     System.out.println(" --- response ---- " + result); 
     b=result.toString(); 

} catch (SocketException ex) { 
    ex.printStackTrace(); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    } 

    return b; 

} 

的Android返回散列值(從logcat的輸入字符串 「ABC」)

11-24 13:56:35.179:INFO/MyApp的(578):48a4yT8WPFCmkTxMSC9WaEtSxJI =

11-24 13 :56:35.179:信息/的System.out(578):---響應---- 48a4yT8WPFCmkTxMSC9WaEtSxJI =

有人能告訴什麼錯在我的代碼?我是雙散列地方

請幫

感謝

回答

1

檢查編碼,確保了用於計算哈希值的實際字節數組是相等的。在.NET中,您使用ASCII編碼和Android ISO-8859-1。這應該不是因爲iso-8859-1是ASCII編碼的自然延伸,但仍檢查數組。 也可以嘗試使用此功能在Android上的SHA1摘要:

/** 
    * Generates SHA-1 digest of the provided data. 
    * 
    * @param data the data to digest 
    * @return SHA-1 digest of the provided data. 
    */ 
    public static byte[] sha1Digest(byte[] data) { 
    MessageDigest mdSha1 = null; 
    try { 
     mdSha1 = MessageDigest.getInstance("SHA-1"); 
    } catch (NoSuchAlgorithmException e1) { 
     Log.e(LOG_TAG, "Error initializing SHA1 message digest"); 
    } 
    mdSha1.update(data); 
    byte[] sha1hash = mdSha1.digest(); 
    return sha1hash; 
    } 
+0

對於我SHA功能我需要發送字符串參數,由用戶輸入的密碼。另外我需要將它的返回類型改爲String來返回我的散列字符串 –

+0

另一件事:爲什麼你要在循環中調用'Base64.encodeToString()'?你應該只用整個哈希數組來調用它。 –

+0

亞感謝我把該行之前的循環 –

相關問題