I have a .NET SOAP web serviec(.asmx) for SHA-1 hashing to get Base64 hash string.
Here is my web service code:
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;
}
}
Here hash returned for input string "abc" is
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
Now, Android code again using SHA-1 and Base64 is:
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 returned hash value is (from logcat for input String "abc")
11-24 13:56:35.179: INFO/myapp(578): 48a4yT8WPFCmkTxMSC9WaEtSxJI=
11-24 13:56:35.179: INFO/System.out(578): --- response ---- 48a4yT8WPFCmkTxMSC9WaEtSxJI=
Can someone tell what's going wrong in my code? Am I double hashing somewhere
Please help
Thanks
Check the encoding, make sure that the actual byte arrays that are used to compute the hash are equal. In .NET you use ASCII encoding and in Android iso-8859-1. This should not mater as the iso-8859-1 is natural extension of the ASCII encoding, but still, check the arrays. Also try using this function for SHA1 digest on Android:
/**
* 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;
}