learningunix
asked on
SecretKeySpec mac and base64
I have a secret key which is already in base64 format.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKe ySpec;
import javax.crypto.SecretKey;
import java.security.Key;
String key = "<base 64 encoded string>";
String key_1 = Base64.decode(key);
try {
Mac mac = Mac.getInstance("HmacSHA1" );
SecretKey secretKey = new SecretKeySpec(key_1.getByt es("UTF-8" ),"HmacSHA 1");
mac.init(secretKey);
String enc = new String(mac.doFinal());
// Base 64 Encode the results
String retVal = Base64Codec.encode(enc);
System.out.println ("result: " + retVal);
} catch (Exception e) {
System.out.println(e.getMe ssage());
}
The output I am getting "result: " is not matching with the output when I execute an equivalent code in python
I am sure something to do with byte array conversion in java and string but cant figure it
NOTE: If I don't do base64 decode and use "new SecretKeySpec(key.getBytes )"
then the output of "result: " is same in java and output from python code.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKe
import javax.crypto.SecretKey;
import java.security.Key;
String key = "<base 64 encoded string>";
String key_1 = Base64.decode(key);
try {
Mac mac = Mac.getInstance("HmacSHA1"
SecretKey secretKey = new SecretKeySpec(key_1.getByt
mac.init(secretKey);
String enc = new String(mac.doFinal());
// Base 64 Encode the results
String retVal = Base64Codec.encode(enc);
System.out.println ("result: " + retVal);
} catch (Exception e) {
System.out.println(e.getMe
}
The output I am getting "result: " is not matching with the output when I execute an equivalent code in python
I am sure something to do with byte array conversion in java and string but cant figure it
NOTE: If I don't do base64 decode and use "new SecretKeySpec(key.getBytes
then the output of "result: " is same in java and output from python code.
ASKER
The python code does base64decode first. I am trying to mimic the code in java.
python uses "base64" and "hmac" library
python uses "base64" and "hmac" library
ASKER
I am sure something to do with base64decode as it coverts to binary on windows and something is getting messed up. The python I am runing is on linux machine
Ok, maybe your statement is a bit unclear... when you said
(I thought that you were saying that when the python code DOES do the bas64 decode and the Java DOESN'T do the decode, that the results line up)
If I don't do base64 decode and use "new SecretKeySpec(key.getBytesdid you mean that when you don't do base64 decode in both java and python the results come out the same?)"
(I thought that you were saying that when the python code DOES do the bas64 decode and the Java DOESN'T do the decode, that the results line up)
What are you using to do your Base64 conversion?
I would say that you are on the mark with byte array conversions being the issue. It is strange that your Base64.decode(key) returns a String, it should really return a byte[] so that no further conversion needs to happen. Yeah, the problem that you are having is because the bytes will be converted to String and then back again at .getBytes("UTF-8") but various encoding schemes will conspire to change the actual bytes on the way through.
I would say that you are on the mark with byte array conversions being the issue. It is strange that your Base64.decode(key) returns a String, it should really return a byte[] so that no further conversion needs to happen. Yeah, the problem that you are having is because the bytes will be converted to String and then back again at .getBytes("UTF-8") but various encoding schemes will conspire to change the actual bytes on the way through.
ASKER
may be i confused u. let me explain it again.
the exact above Java code is running on windows. An exact identical code in python runs from unix.
the value of result does not match.
not sure if something to do with charset on windows
the exact above Java code is running on windows. An exact identical code in python runs from unix.
the value of result does not match.
not sure if something to do with charset on windows
ASKER
The issue is definitely with java. I just installed python on y windows machine and I get same value for "result" when I run python on unix
Not sure why Java won't give me same reuslt. something to with getBytes or new String() which is messing up
Not sure why Java won't give me same reuslt. something to with getBytes or new String() which is messing up
Yeah, I understood that part ok. The part that wasn't clear was the NOTE: right at the end of the original question. (That's what I was referring to in the above comment)
Anyway, regardless, I think the issue is still what I wrote about above... So again, what are you using to do the Base64 conversion? A library? Your own code?
Hang on a sec, you just mentioned "new String()" and this made me check your code again, and yes there is an issue there to. The byte[] returned from mac.doFinal() is being converted to a String aswell. This byte[] should also just be passed directly from mac.doFinal() to base64 encode(), not via a String!
Anyway, regardless, I think the issue is still what I wrote about above... So again, what are you using to do the Base64 conversion? A library? Your own code?
Hang on a sec, you just mentioned "new String()" and this made me check your code again, and yes there is an issue there to. The byte[] returned from mac.doFinal() is being converted to a String aswell. This byte[] should also just be passed directly from mac.doFinal() to base64 encode(), not via a String!
ASKER
I found the solution, I knew it was charset issue.
the correct solution is
SecretKey secretKey = new SecretKeySpec(key_1.getByt es("ISO-88 59-1"),"Hm acSHA1");
String enc = new String(mac.doFinal(), "ISO-8859-1");
PS: I have my own base 64 which accepts string only
the correct solution is
SecretKey secretKey = new SecretKeySpec(key_1.getByt
String enc = new String(mac.doFinal(), "ISO-8859-1");
PS: I have my own base 64 which accepts string only
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks
Your python code is maybe automatically doing the Base64 encode when it create the SecretKeySpec equivalent? I don't know because a) you have posted the python code, and b) I don't know a lot of python anyway ;)