Take the 2-minute tour ×

I'm working on an Android project which send datas to my Webservice and store them in my Database. I'm using a HTTP protocol to connect to my webservice. Using JSON for data format.

I send to the webservice the datas and the HASH (SHA256) of these datas.

Before storing the datas to the database, I verify by using HASH if what I've sent (datas) equals to what The Webservice received. If not, I send an error message.

Sometimes the values of the HASH are differents which cause an error message, and no datas storing in the database

So my question : Is there a another method to verify if the datas aren't altered during the sending operation?

share|improve this question
I believe that's it! Also, or you are using 2 different hash algorithms, or the data is being altered. I don't fully recall this stuff, but I believe there's a initialization vector, this could make 2 different results. –  lpinto.eu Jan 7 '13 at 9:23
Why do you need verification? –  Leonidos Jan 9 '13 at 12:44
Datas can be altered, and I don't want to store altered datas in my database –  13KZ Jan 9 '13 at 13:24
altered by whom? By network or hackers? –  Leonidos Jan 9 '13 at 14:18
If securing the communication channel is all you need, using HTTPS should be enough. –  Olaf Dietsche Jan 10 '13 at 8:28

7 Answers 7

up vote 13 down vote accepted

The hash seems to work for your scenario, since you detect data modifications pretty well.

But a hash can be altered along with the data, so this is not a security measure against malicious attackers. If you're concerned about security, you might be interested in WS-Security.

Essentially, you must either use an encrypted channel (HTTPS) or sign your message.

share|improve this answer

If you don't trust the channel - you should use HTTPS. That's all. Trying to build your own integrity verification mechanism is trying to design your own security protocol and that is the last thing you want to do.

In any case, an unkeyed hash (like SHA256) that you're using is insufficient. An adversary who is capable of modifying the message is also capable of recomputing the hash of the modified text and sending it along with the message. You'll need a stronger primitive: the MAC (Message Authentication Code) http://en.wikipedia.org/wiki/Message_authentication_code

HTTPS give you this and more.

share|improve this answer
Thanks for your answer! May be you know that to use HTTPS I must have the certificat which isn't free. I know that using hash like SHA256 isn't a good way but we don't the certificate to use a secure channel –  13KZ Jan 16 '13 at 9:02
@zim As long as you use the certificate for your webservice and android app alone, there is no need to buy one. You can use a self signed certificate for this task. –  Olaf Dietsche Jan 16 '13 at 11:17
+1 for MAC and promoting HTTPS –  Olaf Dietsche Jan 16 '13 at 12:18

Hashing techniques would be the best choice here.

You can use any hashing algorithm like HmacSHA1 or MD5,etc.

When you are passing your data to server using Post or Get, first, create a token from the data by using any hashing algorithm. (please see below function that converts data into HMAC SHA1)

When you pass this data, pass the token as well to server. Now server will also use the same hashing algorithm that client has used, and server will create the token from the data that is passed with the request.

After that server will match the token generated with the token passed with request.

If both the tokens matches, the data that is passed with request is not tampered otherwise the data is tampered.

You can use following method to create token for your data:

     * Encrypts the data passed to it using Hmac-SHA1.
     * @param dataToEncrypt
     *            data that is to be encrypted.
     * @return The token that is generated after encrypting data.
    public static String convertDataToHmacSHA1(final String dataToEncrypt) {
        String returnString;
        try {
            // Get an hmac_sha1 key from the raw key bytes
            final byte[] keyBytes = HMAC_SHA1_KEY.getBytes();
            final SecretKeySpec signingKey = new SecretKeySpec(keyBytes,

            // Get an hmac_sha1 Mac instance and initialize with the signing key
            final Mac mac = Mac.getInstance("HmacSHA1");

            // Compute the hmac on input data bytes
            final byte[] rawHmac = mac.doFinal(dataToEncrypt.getBytes());

            final StringBuffer stringBuffer = new StringBuffer();
            for (byte b : rawHmac) {
                stringBuffer.append(String.format("%02x", b));
            returnString = stringBuffer.toString();
            Log.e("Token", returnString);
            return returnString;
        } catch (Exception e) {
            Log.e(TAG, "" + e);
        return returnString;
share|improve this answer
+1 for HMAC. You shouldn't convert exceptions to some arbitrary string; let the caller handle exceptions. –  Olaf Dietsche Jan 16 '13 at 12:16
Thank you Olaf. Actually, i picked this snippet from one of my code, so I forgot to remove it. –  Shrikant Jan 16 '13 at 12:31

currently you use a hash to verify the integrity of the data - assumming you use the exact same hashing on both ends this means youre getting corrupted data.

instead of just detecting data coruuption you could encode the data in an error correcting code so that you could reconstruct the original data at the receiving end even if it was corrupted on the way there

you can find such a library in the answer to this question - Java: ECC (error correcting code) library?

share|improve this answer
If he's using HTTP over TCP the data isn't corrupted in transit. –  Samuel Edwin Ward Jan 14 '13 at 20:50
@Samuel Edwin Ward: and a MITM attack on a still-in-development android app is more plausible?! –  radai Jan 15 '13 at 4:40
I would consider them both very unlikely. It's much more likely that there's a logic error in the application code. But I would say that a MITM attack of some sort is more likely. It could be something that isn't specifically targeting this application. –  Samuel Edwin Ward Jan 15 '13 at 14:21

I think your method is a good one.

you have an heavy solution in 3 steps : step 1 : send the data to android step 2 : android receive the data and inform the web server what he get step 3 : the server check every field and inform android if the orverall is correct or not.

but i think this solution is too heavy for most the case, it was to answer your question if there is another solution or not.

share|improve this answer

Do you need to read back the data, If not just hash it once and compare the hashes.

Dependant on the frequency of the hash being wrong could you give the application five attempts to getting it right before the error message.

Have you tried other algorithms like md5, ripe or crc? Maybe they are more efficient.

In my experience for small string i use crc but for login details i go with sha256 or sha512 and i just hash the password and compare the hashes. Then you dont have passwords sitting in your database.

Hope this helps!

share|improve this answer

Correct me if I'm wrong, but you are hashing in an attempt to detect one of two things.

  1. Detect a "Man in the Middle Attack." (MITM) See here for more information.
  2. Detect an unreliable network.

@Samuel Edwin Ward and @radai were talking about these two above.

Both concerns have reasonably good existing solutions that DO NOT involve you explicitly hashing your data.

Firstly, for reducing the likelihood of an MITM attack, use HTTPS. The client can establish the identity of the server with some confidence, and it also does quite a good job of preventing eavesdropping.

Secondly, to address your concerns about an unreliable network, use TCP...


I'm guessing you haven't done anything special (like use a UDP network or something), and your web service already uses TCP.

The issues you are seeing with your hashing comparison is likely to be due to an incorrect assumption in your application logic. I would suggest that you are comparing hashes of the wrong things.

As one of many examples that come to mind, some web servers will add things to the HTTP request as it is processed. This is how proxies work, for instance. This will give you different results when comparing a hash of the HTTP request as sent by the device, and a hash of the HTTP request as eventually received by the web server.

I suggest you read the inline links I have provided to assure yourself that your concerns about corrupted data have largely been addressed by existing solutions. If they aren't, at least you'll have a better understanding of why you feel you need to hash your data. :)

share|improve this answer

Your Answer


