Translate HmacSHA1 checksum generating method from Java to PHP - java

I would like to translate the following Java method to PHP:
private byte[] generateChecksum(byte[] inData){
try{
byte[] b_key = secretValue.getBytes("ISO-8859-1");
SecretKeySpec sha1Key = new SecretKeySpec(b_key, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(sha1Key);
byte[] sigBytes = mac.doFinal(inData);
return sigBytes;
}catch(Exception e){
log.error("problem create hash: " + e);
return null;
}
}
I came up with the following, but it doesn't seem to be producing the same results as the Java method:
private function generateChecksum ( $inData ) {
try {
$hash = hash_hmac( 'sha1', $inData, $this->secretValue, TRUE );
return $this->getBytes( $hash );
} catch (Exception $e) {
return null;
}
}

I resolved it. The issue was caused by passing the $inData to hash_hmac( ) as a byte array instead of a string.

Related

Passing a Base64 encoded String into sha512 function gives different result than when hard coded

I'm coding in Android Studio and I'm trying to create base64 encoded and sha512 hashed String.
The functions are:
private String getBase64(String data){
try{
byte[] enc = data.getBytes("UTF-8");
return Base64.encodeToString(enc, Base64.DEFAULT);
}catch (Exception e){
e.printStackTrace();
return null;
}
}
private String getSHA(String data){
try {
MessageDigest mda = MessageDigest.getInstance("SHA-512");
byte[] digesta = mda.digest(data.getBytes("UTF-8"));
return convertByteToHex(digesta);
}catch(Exception e){
e.printStackTrace();
return null;
}
}
public String convertByteToHex(byte data[]) {
StringBuilder hexData = new StringBuilder();
for (byte aData : data)
hexData.append(String.format("%02x", aData));
return hexData.toString();
}
Then calling them:
// line below prints VGVzdDox as it should
Log.d("GO", "Working Base64: " + getBase64("Test:1"));
// line below prints: 3553AF9EDC389314B0F7354B51FEA7EB089C039EA77A0FD7BD61798A8DD14B1292B353B9E00789B2698B072AF5B05417DDDAA1870ADF9E1DE9C1F96D9465DF56
// as it should
Log.d("GO", "Working SHA: " + getSHA("VGVzdDox"));
String b = getBase64("Test:1");
// line below prints VGVzdDox again, as it should
Log.d("Base64", b);
String s = getSHA(b);
// Now this line prints a7d1bdc5d6497d787b35ce52774365150a2e21084958ffc14570367f3764b938fc1191d06006f1908084518c9697cbff3f2830a1ac003ef8ace36a0667dce92d
// Not sure why?
Log.d("SHA", s);
So that last output is wrong. However the getBase64 is right and the getSHA also when hard coding the base64 encoded String. And I have no idea why.
This is just the main activity, no other code is executed.
it seems like your String
b
have a new line at the end, i tested it with an online sha 512 generator with the String:
"VGVzdDox" and
"VGVzdDox
"
output of the first one is:
3553AF9EDC389314B0F7354B51FEA7EB089C039EA77A0FD7BD61798A8DD14B1292B353B9E00789B2698B072AF5B05417DDDAA1870ADF9E1DE9C1F96D9465DF56
the out put for the second is:
A7D1BDC5D6497D787B35CE52774365150A2E21084958FFC14570367F3764B938FC1191D06006F1908084518C9697CBFF3F2830A1AC003EF8ACE36A0667DCE92D
so get rid of the line seperator maybe with the method Stirng.trim(), but i didn't tested it
Found it, had to change:
return Base64.encodeToString(enc, Base64.DEFAULT);
to
return Base64.encodeToString(enc, Base64.NO_WRAP);

Sending request to REST API using oAuth - fatsecret API

I try to send valid request to REST API which uses oAuth. I keep receiving respond : "Invalid signature"
Here's steps I do to generate request:
Build Request:
public String buildRequest() {
ArrayList<String> params = new ArrayList<>(generateParams());
params.add("oauth_signature=" + sign(buildSignatureBaseString()));
Collections.sort(params);
return join(params.toArray(template), "&");
}
Creating Signature Base String:
public String buildSignatureBaseString(){
StringBuilder builder = new StringBuilder();
builder.append(METHOD);
builder.append("&");
builder.append(percentEncoding(URL));
builder.append("&");
builder.append(percentEncoding(join(generateParams().toArray(template), "&")));
return builder.toString();
}
Generating parameters sorted in natural order:
private ArrayList<String> generateParams() {
ArrayList<String> params = new ArrayList<>();
params.add("oauth_consumer_key=" + "...");
params.add("oauth_signature_method=HMAC-SHA1");
params.add("oauth_timestamp=" + Long.valueOf(System.currentTimeMillis() / 1000).toString());
params.add("oauth_nonce=" + getNonce());
params.add("oauth_version=1.0");
params.add("format=json");
params.add("method=foods.search");
params.add("search_expression=pasta");
Collections.sort(params);
return params;
}
Creating Signature Base String:
public String buildSignatureBaseString(){
StringBuilder builder = new StringBuilder();
builder.append(METHOD);
builder.append("&");
builder.append(percentEncoding(URL));
builder.append("&");
builder.append(percentEncoding(join(generateParams().toArray(template), "&")));
return builder.toString();
}
Generating signature with HMAC-SHA1:
public String sign(String sbs) {
String key = <SharedSecret> + "&";
SecretKeySpec sk = new SecretKeySpec(key.getBytes(Charset.forName("UTF-8")), ALGORITHM);
try {
Mac m = Mac.getInstance(ALGORITHM);
m.init(sk);
byte[] hmacEncoded = m.doFinal(sbs.getBytes(Charset.forName("UTF-8")));
byte[] base64Encoded = Base64.encode(hmacEncoded, Base64.DEFAULT);
return Uri.encode(new String(base64Encoded, Charset.forName("UTF-8")));
} catch (java.security.NoSuchAlgorithmException e) {
Log.w("FatSecret_TEST FAIL", e.getMessage());
return null;
} catch (java.security.InvalidKeyException e) {
Log.w("FatSecret_TEST FAIL", e.getMessage());
return null;
}
}
Could someone more experienced in this matter help?
Regards
The param entries from generateParams all are in the form tag=value. Your sign method seems only to return a value.
And: Are you sure the sign method does not throw? I this case you would return null, which you should check in the caller method and only add it to the params if it is not null

how to take diff of two versions of perforce depot file

how to check if the file content is same as the revision in server perforce JAVA API. Before updating any file into perforce depot, I want to check is there any difference in content of local file and the depot file. if there is no difference then ignore to submit that file.
I think you want the getDiffFiles() method:
https://www.perforce.com/perforce/r15.1/manuals/p4java-javadoc/com/perforce/p4java/impl/mapbased/client/Client.html#getDiffFiles
Alternatively, for the specific thing you're doing (not submitting unchanged files), just use the "leaveUnchanged" submit option rather than doing the same work yourself.
Yes simple to do. Just generate a MD5 hash of the original file and before updating again generate a MD5 hash of the new file.
Now compare the hashes of both the files. If both are same, then the contents of both the files are same and if not then they are different and you are good to update.
Here is an utility to generate and check MD5 easily,
public class MD5Utils {
private static final String TAG = "MD5";
public static boolean checkMD5(String md5, File updateFile) {
if (TextUtils.isEmpty(md5) || updateFile == null) {
Log.e(TAG, "MD5 string empty or updateFile null");
return false;
}
String calculatedDigest = calculateMD5(updateFile);
if (calculatedDigest == null) {
Log.e(TAG, "calculatedDigest null");
return false;
}
Log.v(TAG, "Calculated digest: " + calculatedDigest);
Log.v(TAG, "Provided digest: " + md5);
return calculatedDigest.equalsIgnoreCase(md5);
}
public static String calculateMD5(File updateFile) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "Exception while getting digest", e);
return null;
}
InputStream is;
try {
is = new FileInputStream(updateFile);
} catch (FileNotFoundException e) {
Log.e(TAG, "Exception while getting FileInputStream", e);
return null;
}
byte[] buffer = new byte[8192];
int read;
try {
while ((read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
String output = bigInt.toString(16);
// Fill to 32 chars
output = String.format("%32s", output).replace(' ', '0');
return output;
} catch (IOException e) {
throw new RuntimeException("Unable to process file for MD5", e);
} finally {
try {
is.close();
} catch (IOException e) {
Log.e(TAG, "Exception on closing MD5 input stream", e);
}
}
}
}

How to convert this MD5 encode PHP to java

I have simply code in PHP like that
$hash = md5("testtesttest", TRUE);
echo $hash.'<br>';
$hash = md5($hash . "test", TRUE);
echo $hash.'<br>';
With 2 line fisrt in java, it's working good with my code
public static void main(String[] args) {
// String str = new String(md5x16("test"));
byte[] input = md5x16("testtesttest");
String t = new String(input);
System.out.println(t);
}
public static byte[] md5x16(String text) {
try {
MessageDigest digester = MessageDigest.getInstance("MD5");
digester.update(text.getBytes());
byte[] md5Bytes = digester.digest();
return md5Bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
But in line 3 and 4 in PHP, I can't do the same in Java
If I parse to String and add a "test" to it, I will get another result with PHP
Iraklis should be right. md5() gives you a hex-encoded output string by default. You only get the unencoded bytes like in Java by passing in TRUE for the optional $raw_output argument.
the lengths range from 29 to 32
hexString.append( Integer.toHexString(0xFF & message[ i ] ) );
function makeBrokenMD5($s) {
$hash= md5($s, TRUE);
$bytes= preg_split('//', $hash, -1, PREG_SPLIT_NO_EMPTY);
$broken= '';
foreach ($bytes as $byte)
$broken.= dechex(ord($byte));
return $broken;
}`

Flex File reading problem

i am having a problem in reading a file from Flex. The file contains a base64encoded string. when i read the file i get the length as 47856 and the decoded base64 byte array length as 34157.
When i read the same File from java i get the length as 48068 and 35733 respectively.
What is the problem?
private function init():void{
var file:File = File.desktopDirectory.resolvePath("Files/sample.txt");
stream = new FileStream();
stream.open(file, FileMode.READ);
var str:String = stream.readUTFBytes(stream.bytesAvailable);
stream.close();
str = str.replace(File.lineEnding, "\n");
contents.text = str;
fileName.text = file.name;
}
public function playSound(contents:String):void{
try{
var byteData: ByteArray;
byteData = new ByteArray();
byteData.writeUTFBytes(contents);
var dec:Base64Decoder = new Base64Decoder();
dec.decode(contents);
byteData = dec.toByteArray();
Alert.show("byte Array " + byteData.toString().length +" :: " +contents.length);
}
And this is my java code for reading the file...Whatever result i am expecting is achieved in the java side.
private static String readFile(String path) throws IOException {
FileInputStream stream = new FileInputStream(new File(path));
try {
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
return Charset.defaultCharset().decode(bb).toString(); }
finally { stream.close();
}
}
Java Code where i am printing the length
byte[] decodedBase64 = new byte[byteLength];
String speexData = null;
try {
speexData = readFile(userDir +"//" +xmlFileName);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// System.out.println("sa " + sa);
try{
decodedBase64= Base64.decodeToByteArray(speexData);
System.out.println("decodednase64 length " + decodedBase64.length +" :: " +speexData.length());
}
catch(Exception e){
}
You would have to post your java code to show what you're doing there, as well.
However, without knowing more, I could take a guess and say that when you replace the line ending, you may be removing a byte each time (if it was \r\n and you're making it \n, for example).

Categories