5

I need your help. My java and python scripts not getting the ame sha-1 value of a string:

hash.py

 # -*- coding: utf-8 -*-
 import hashlib

 username = raw_input('username:')
 timestamp = raw_input('timestamp:')

 app_id = 'dad'
 secret_key = 'dadda'

 print 'The hashed string is: ' , hashlib.sha1( username + timestamp + app_id + secret_key ).hexdigest()

hash.java

 public static String generateSHA1(String password)
{
    String sha1 = "";
    try
    {
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(password.getBytes("UTF-8"));
        sha1 = byteToHex(crypt.digest());

    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return sha1;
}

private static String byteToHex(final byte[] hash)
{
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
        formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
}

UPDATE: Assuming password is already the concatenated: username, timestamp, app_id and secret_key

Is there something I missed? I think there is something wrong with my java code re. UTF-8 outputting this: \xe2\x80\x8b but I couldn't figure it out. Any help will be appreciated. Thanks.

8
  • Is this behavior happening for all values of user name/timestamp? Can you post a sample user/timestamp pair you are trying? Commented Nov 19, 2015 at 15:38
  • @SanjayT.Sharma username: [email protected] timestamp: 1447943648 Commented Nov 19, 2015 at 15:40
  • I can't reproduce your issue here; I get the same eeae0d665ed71f3d8f4e3d344fda1c3735dc46c0 hashed value for both using your sample inputs. Commented Nov 19, 2015 at 15:48
  • @SanjayT.Sharma can you check if it's outputting: \xe2\x80\x8b? Commented Nov 19, 2015 at 15:50
  • Not sure I understand, check which output? I think the problem lies in the way you are accepting user input or calling your client code. Can you hardcode the inputs and check the SHA-1 output instead of reading from console? Commented Nov 19, 2015 at 16:02

1 Answer 1

1

Ensure that both inputs use exactly the same format and encoding and try to use HMAC library.

Java:

String key = "2b5ba589b618ff2485f3391e425f86f0f405fd8e";
String data = "Something you want to keep secret!";
byte[] decodedKey = Hex.decodeHex(key.toCharArray());
SecretKeySpec keySpec = new SecretKeySpec(decodedKey, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(keySpec);
byte[] dataBytes = data.getBytes("UTF-8");
byte[] signatureBytes = mac.doFinal(dataBytes);
String signature = new String(Base64.encodeBase64(signatureBytes), "UTF-8");

System.out.println("key = " + key);
System.out.println("data = " + data);
System.out.println("signature = " + signature);

Python:

import hmac
import hashlib

key = "2b5ba589b618ff2485f3391e425f86f0f405fd8e"
data = "Something you want to keep secret!"
decodedKey = key.decode("hex")
hmac = hmac.new(decodedKey, data.encode('UTF-8'), hashlib.sha1)
signature = hmac.digest().encode('base64')

print "key =", key
print "data =", data
print "signature =", signature

Both signature outputs should be the same.

Sign up to request clarification or add additional context in comments.

1 Comment

Small note: the input format of the HMAC should be well defined, e.g. it should not be possible for an attacker to change ab | c into a | bc (same hashed value for different fields).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.