即使在Android和.NET中输入相同的字符串后,仍有两个不同的哈希值

时间:2011-11-24 08:36:16

标签: android web-services hash android-ksoap2 sha

我有一个用于SHA-1哈希的.NET SOAP Web服务(.asmx)来获取Base64哈希字符串。

这是我的网络服务代码:

 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 =

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

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:INFO / System.out(578):--- response ---- 48a4yT8WPFCmkTxMSC9WaEtSxJI =

有人可以告诉我的代码出了什么问题吗?我在某个地方进行双重扫描

请帮忙

由于

1 个答案:

答案 0 :(得分: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;
  }