【问题标题】:Compare two hash strings generated using SHA-1 in Android比较 Android 中使用 SHA-1 生成的两个哈希字符串
【发布时间】:2011-11-25 22:17:37
【问题描述】:

这是我的 Android 代码流程:

我正在使用 SHA-1 散列来散列用户通过 EditText 输入的密码。我在这里得到一个哈希字符串作为输出。

之后,我调用了一个 SOAP Web 服务(使用 .NET 框架创建),该服务使用 ASCII 编码执行相同的 SHA-1 哈希并返回另一个哈希字符串。

现在由于两种情况下的输入字符串相同,我的哈希字符串与预期相同。 请参阅下面的 logcat。但是当我比较哈希字符串时,我没有得到预期的结果

这是我的 Android 代码,后面是 logcat:

           package com.kar.encodePassword;
           import java.io.IOException;
           import java.io.UnsupportedEncodingException;
           import java.net.SocketException;
           import java.security.MessageDigest;
           import java.security.NoSuchAlgorithmException;
           import org.ksoap2.SoapEnvelope;
           import org.ksoap2.serialization.SoapObject;
           import org.ksoap2.serialization.SoapPrimitive;
           import org.ksoap2.serialization.SoapSerializationEnvelope;
           import org.ksoap2.transport.HttpTransportSE;
           import org.xmlpull.v1.XmlPullParserException;
           import android.app.Activity;
           import android.os.Bundle;
           import android.util.Base64;
           import android.util.Log;
           import android.view.View;
           import android.widget.Button;
           import android.widget.EditText;
           import android.widget.Toast;

   public class PaswordencodingActivity extends Activity {
       /** Called when the activity is first created. */

 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 (UnsupportedEncodingException e) {                                          
                      e.printStackTrace();
        } catch (IOException e) {   
            e.printStackTrace();                    
                      }
            }
            else{
       Toast.makeText(PaswordencodingActivity.this, "this is a negative onClick", Toast.LENGTH_LONG).show();
            }

           }

          });


        }


private static String convertToHex(byte[] data) throws java.io.IOException 
 {
        System.out.println("data received is"  +data);

        StringBuffer sb = new StringBuffer();
        String hex=null;

        hex=Base64.encodeToString(data, 0, data.length, NO_OPTIONS);

        for (int i = 0; i < data.length; i++) 
        {            
            if (hex.length() == 1) 
            {
                sb.append('0');
            }
            sb.append(hex);
        }

       return sb.toString();
    }

public void SHA1(String text) throws IOException
{
    MessageDigest mdSha1 = null;
    try 
    {
      mdSha1 = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e1) {
      Log.e("myapp", "Error initializing SHA1 message digest");
    }
    mdSha1.update(text.getBytes("iso-8859-1"), 0, text.length());
    byte[] data = mdSha1.digest();
    hash=convertToHex(data);

    System.out.println("data going is"  +data);
    System.out.println("hash value"+hash);

    try
    {
        result2=call3(password);
        if(result2.equalsIgnoreCase(hash.toString()))
        System.out.println("success");


    } catch (XmlPullParserException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   

        }

public String call3(String pass) throws XmlPullParserException
{
        String b=""; 

        SoapObject request = new SoapObject(namespace2, method_name);      
        request.addProperty("str",pass);

        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;   

}
}

基本上,当我尝试比较两个哈希字符串时,我没有得到结果

为什么会这样?谁能帮忙?

Logcat:

        11-25 17:09:50.899: INFO/System.out(275): data received is[B@44ef8eb0
        11-25 17:09:50.909: INFO/System.out(275): data going is[B@44ef8eb0
        11-25 17:09:50.909: INFO/System.out(275): hash valueUGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:09:50.909: INFO/System.out(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:09:50.909: INFO/System.out(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:09:50.909: INFO/System.out(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:09:50.909: INFO/System.out(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:09:50.909: INFO/System.out(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:09:50.909: INFO/System.out(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:09:50.909: INFO/System.out(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:10:01.730: INFO/myapp(275): UGGpBypVug3K+/4xONpqv9wkFd8=
        11-25 17:10:01.730: INFO/System.out(275):  --- response ---- UGGpBypVug3K+/4xONpqv9wkFd8=

【问题讨论】:

    标签: android web-services hash ksoap2 sha


    【解决方案1】:

    试试

    result2 = result2.trim();
    hash = hash.trim();
    
    System.out.println("result2='" + result2 + "'");
    System.out.println("hash ='" + hash + "'");
    
    if(result2.equalsIgnoreCase(hash))
       System.out.println("success");
    

    如果这没有帮助,请检查实际的数组:

    byte[] a = result.toString().getBytes() 
    byte[] b = hash..getBytes();
    

    如果数组不相等,则表示字符串的编码不同。

    【讨论】:

    • 很好,两者都不起作用尝试了它们。现在告诉我如何更改 android 端代码的编码。我的 .net 网络服务是 ASCII 顺便说一句
    • 我尝试在我的 android 应用程序和服务器端代码中同时使用 ASCII.. 仍然没有正确的结果:(
    【解决方案2】:

    我认为你将byte[]转换为String的方式不对,应该是这样的:

    hash = new String(data);
    

    另外你做的比较错了,应该是这样的:

    if(result2.equals(hash))
    

    在我看来,您根本不应该将byte[] 转换为String。使用Arrays.equals(byteArray1,byteArray2);。您的数据是10s 的随机位。将其转换为String 可以通过多种方式完成,但没有任何意义。

    【讨论】:

    • 对不起,我没有得到你的第一点转换 hash=new String(data);你能解释一下吗?另外,我尝试使用 equals、equalsIgnoreCase 和所有可能的字符串比较方法,但我仍然没有得到“成功”的结果
    【解决方案3】:

    如果您对源自String 的数据应用散列算法,则需要使用相同的字符编码来检索字节。

    text.getBytes("iso-8859-1")
    

    不同的字符集可以不同地表示字节值。

    【讨论】:

    • 好的,所以在我的服务器端我使用 ASCII 所以在 android 端我可以写 text.getBytes("ASCII")
    • 确定之后我该如何比较?我应该像@peceps 提到的那样使用equalsIgnoreCase 进行比较还是比较字节数组?
    • 请看这个:pastie.org/2919436。这个对吗 ?如果我现在使用 String.equals 我会得到我的输出吗?
    • 但它不起作用,伙计!这就是问题..请帮助!!
    猜你喜欢
    • 1970-01-01
    • 2014-03-31
    • 2019-08-15
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 2013-09-08
    • 2011-03-27
    • 1970-01-01
    相关资源
    最近更新 更多