1

我有一个 .NET SOAP web serviec(.asmx) 用于 SHA-1 散列以获取 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返回的哈希值是(来自输入字符串“abc”的logcat)

11-24 13:56:35.179: 信息/myapp(578): 48a4yT8WPFCmkTxMSC9WaEtSxJI=

11-24 13:56:35.179: INFO/System.out(578): --- 响应 ---- 48a4yT8WPFCmkTxMSC9WaEtSxJI=

有人可以告诉我的代码出了什么问题吗?我在某处双重哈希吗

请帮忙

谢谢

4

1 回答 1

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;
  }
于 2011-11-24T08:50:09.113 回答