How to generate HMAC-SHA1 Signature in android? - android

This is my base String:
String args ="oauth_consumer_key="+enc(consumerkey) +
"&oauth_nonce="+enc(generateNonce()) +
"&oauth_signature_method=HMAC-SHA1" +
"&oauth_timestamp="+ timestamp +
"&oauth_token="+enc(Home.consToken) +
"&oauth_verifier="+verifier+"&oauth_version=1.0";
String base ="POST&"+enc("https://api.linkedin.com/uas/oauth /accessToken") +"&"+ enc(args);
String signature =computeHmac(base,consumer_secret+"&"+secretToken);
This is my Header:
String header = "OAuth " +
"oauth_consumer_key=\""+ enc(consumerkey)+ "\"," +
"oauth_nonce=\""+ enc(generateNonce()) + "\"," +
"oauth_signature_method=\"HMAC-SHA1\"," +
"oauth_timestamp=\""+ timestamp + "\"," +
"oauth_token=\""+Home.consToken + "\"," +
"oauth_signature=\""+enc(signature)+"\","+
"oauth_verifier=\""+verifier +"\","+
"oauth_version=\""+1.0+"\"" ;
I am using following method to generate Signature:
public String computeHmac(String baseString, String key)
throws NoSuchAlgorithmException, InvalidKeyException, IllegalStateException, UnsupportedEncodingException
{
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secret = new SecretKeySpec(key.getBytes(), mac.getAlgorithm());
mac.init(secret);
byte[] digest = mac.doFinal(baseString.getBytes());
byte[] result=Base64.encodeBase64(digest);
return new String(result);
}
while executing this code i am getting the following error...
oauth_problem=signature_invalid&
oauth_problem_advice=com.linkedin.security.auth.pub.LoginDeniedInvalidAuthTokenException
can anybody help me out this?
Thanks...

Femi's answer is absolutely correct, however, it wasn't obvious for me what exactly is intval(b). As i understood it's b & 0xFF.
Also I applied some optimizations (that I found here) and here is my code:
private static String hmacSha1(String value, String key)
throws UnsupportedEncodingException, NoSuchAlgorithmException,
InvalidKeyException {
String type = "HmacSHA1";
SecretKeySpec secret = new SecretKeySpec(key.getBytes(), type);
Mac mac = Mac.getInstance(type);
mac.init(secret);
byte[] bytes = mac.doFinal(value.getBytes());
return bytesToHex(bytes);
}
private final static char[] hexArray = "0123456789abcdef".toCharArray();
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}

Messy, but I'm using this:
static String hash_hmac(String type, String value, String key)
{
try {
javax.crypto.Mac mac = javax.crypto.Mac.getInstance(type);
javax.crypto.spec.SecretKeySpec secret = new javax.crypto.spec.SecretKeySpec(key.getBytes(), type);
mac.init(secret);
byte[] digest = mac.doFinal(value.getBytes());
StringBuilder sb = new StringBuilder(digest.length*2);
String s;
for (byte b : digest){
s = Integer.toHexString(intval(b));
if(s.length() == 1) sb.append('0');
sb.append(s);
}
return sb.toString();
} catch (Exception e) {
android.util.Log.v("TAG","Exception ["+e.getMessage()+"]", e);
}
return "";
}
You then invoke it like this:
hash_hmac("HmacSHA1", value, key);

Related

building encryption SHA 1 from Parameter for android to json parse

I have problem with build Encryption from String to SHA 1 encrypt maybe in here can help me
This my Parameter
String AgentID = "7001";
String AgentPIN = "68820025";
String ScreetKey = "63e3cd0a";
String AgentTrxID = "201802090013";
String AgentStoreID = "01010101";
String pdam = pdam1;
String CustomerID =
edit_nomorpelangganpdam.getText().toString().trim();
String DateTimeRequest = (String)
DateFormat.format("yyyyMMddHHmmss", new Date());
And this my code for SHA 1
StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4) & 0x0;
int two_halfs = 0;
do {
buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}
public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes("UTF-8"), 0, text.length());
byte[] sha1hash = md.digest();
return convertToHex(sha1hash);
}
I want to make like this Encryption
93d97a890c312a7f33ca2c393ec070a7e1b42cdc
Please try this code
// Call this method where you wont
encryptString("Your String value")
private static String encryptString(String value)
{
String sha1 = "";
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(value.getBytes("UTF-8"));
sha1 = byteToHexadecimal(crypt.digest());
}
catch(NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
}
return sha1;
}
private static String byteToHexadecimal(final byte[] hash)
{
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}

How to write a hash function in Android similar to the Python function?

I am currently developing a distributed system application. I want to verify a Python generated hash in the Android application. I have a python method to do hashing in given string variables.
This is the python function and it works well.
hash_value = hashlib.sha1("PARAMETER123".encode("UTF-8")).hexdigest()
I want to implement the same function in my Android application. I hope some expert can help as soon as possible.
You can try the following code snippet,
String text = "PARAMETER123";
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] textBytes = text.getBytes("UTF-8");
md.update(textBytes, 0, textBytes.length);
byte[] sha1hash = md.digest();
String encrypted_text = = convertToHex(sha1hash);
and the convertToHex() method
private static String convertToHex(byte[] data) {
StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4) & 0x0F;
int two_halfs = 0;
do {
buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}
This will convert a UTF-8 based text into a SHA1 hex.
Reference: https://stackoverflow.com/a/5980789/2506025
Here is a simple SHA1 method for Java:
String sha1Hash( String toHash )
{
String hash = null;
try
{
MessageDigest digest = MessageDigest.getInstance( "SHA-1" );
byte[] bytes = toHash.getBytes("UTF-8");
digest.update(bytes, 0, bytes.length);
bytes = digest.digest();
// This is ~55x faster than looping and String.formating()
hash = bytesToHex( bytes );
}
catch( NoSuchAlgorithmException e )
{
e.printStackTrace();
}
catch( UnsupportedEncodingException e )
{
e.printStackTrace();
}
return hash;
}
// http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex( byte[] bytes )
{
char[] hexChars = new char[ bytes.length * 2 ];
for( int j = 0; j < bytes.length; j++ )
{
int v = bytes[ j ] & 0xFF;
hexChars[ j * 2 ] = hexArray[ v >>> 4 ];
hexChars[ j * 2 + 1 ] = hexArray[ v & 0x0F ];
}
return new String( hexChars );
}
You can include those methods and call sha1hash.

how to encode pass with sha1 and Base64?

I need provide hashing password with sha1 and Base64 like next:
base64(sha1(password))
here is what i tried for:
private static String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9)) {
buf.append((char) ('0' + halfbyte));
}
else {
buf.append((char) ('a' + (halfbyte - 10)));
}
halfbyte = data[i] & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}
public static String SHA1(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(password.getBytes("iso-8859-1"), 0, password.length());
byte[] sha1hash = md.digest();
return convertToHex(sha1hash);
}
and than :
String encodedPass = Base64.encodeToString(password.getBytes(), Base64.DEFAULT);
but this doesn't work correctly...
Maybe there some mistake or some much easier way to do it?
the problem was next:
convertToHex(sha1hash) - return string, but for correct work of Base64 I was needed to put byte [] here:
Base64.encodeToString(byte[], Base64.DEFAULT);
so solution is pretty simple:
public static String encodePassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String result;
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(password.getBytes("iso-8859-1"), 0, password.length());
byte[] sha1hash = md.digest();
result = Base64.encodeToString(sha1hash, Base64.DEFAULT);
result = result.substring(0, result.length()-1);
return result;
}

Generating ECPublicKey from byte array

I get a 64 uncompressed public key and need to run ECDH to generate a shared secret.
In order to call ECDH I need to convert the byte array to PublicKey and I am using the following code I have found in this forum:
public static void setOtherPublicKey(byte[] publicKeyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException
{
try {
//EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
KeyFactory generator = KeyFactory.getInstance("EC");
//PrivateKey privateKey = generator.generatePrivate(privateKeySpec);
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
blePubKey = generator.generatePublic(publicKeySpec);
} catch (Exception e) {
throw new IllegalArgumentException("Failed to create KeyPair from provided encoded keys", e);
}
}
This code throws an InvalidKeySpecException.
As example, the public key of the other party is:
9b5e9a5a971877530c9cadbbea93c2ee2483d65052678f745bad79f110173520
54019832e11376537a76c4defd0b3dfdc667a974239147f323cdcfd2baa39892
Adding the code after getting the answers below:
public static void setOtherPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException
{
// first generate key pair of your own
ECPublicKey pubKey = (ECPublicKey) SecPage.g_kpA.getPublic();
ECParameterSpec params = pubKey.getParams();
int keySizeBytes = params.getOrder().bitLength() / Byte.SIZE;
// get the other party 64 bytes
//byte [] otherPub = crypto.getBlePubKeyBytes();
byte[] otherPub = hexStringToByteArray("ac2bdd28fce5c7b181b34f098b0934742281246ed907a5f646940c1edcb724e7c7358356aebea810322a8e324cc77f376df4cabd754110ad41ec178c0a6b8e5f");
ByteArrayBuffer xBytes = new ByteArrayBuffer(33);
ByteArrayBuffer yBytes = new ByteArrayBuffer(33);
byte[] zero = {(byte)0x00};
xBytes.append(zero, 0, 1);
xBytes.append(otherPub, 0, 32);
yBytes.append(zero, 0, 1);
yBytes.append(otherPub, 32, 32);
// generate the public key point
BigInteger x = new BigInteger(xBytes.buffer());
BigInteger y = new BigInteger(yBytes.buffer());
ECPoint w = new ECPoint(x, y);
// generate the key of the other side
ECPublicKeySpec otherKeySpec = new ECPublicKeySpec(w , params);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
blePubKey = (ECPublicKey) keyFactory.generatePublic(otherKeySpec);
}
Well, whaty'know, you can actually do this... explanation in the comments.
public class ECDHPub {
private static ECPublicKey decodeECPublicKey(ECParameterSpec params,
final byte[] pubkey) throws NoSuchAlgorithmException,
InvalidKeySpecException {
int keySizeBytes = params.getOrder().bitLength() / Byte.SIZE;
int offset = 0;
BigInteger x = new BigInteger(1, Arrays.copyOfRange(pubkey, offset,
offset + keySizeBytes));
offset += keySizeBytes;
BigInteger y = new BigInteger(1, Arrays.copyOfRange(pubkey, offset,
offset + keySizeBytes));
ECPoint w = new ECPoint(x, y);
ECPublicKeySpec otherKeySpec = new ECPublicKeySpec(w, params);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
ECPublicKey otherKey = (ECPublicKey) keyFactory
.generatePublic(otherKeySpec);
return otherKey;
}
private static byte[] encodeECPublicKey(ECPublicKey pubKey) {
int keyLengthBytes = pubKey.getParams().getOrder().bitLength()
/ Byte.SIZE;
byte[] publicKeyEncoded = new byte[2 * keyLengthBytes];
int offset = 0;
BigInteger x = pubKey.getW().getAffineX();
byte[] xba = x.toByteArray();
if (xba.length > keyLengthBytes + 1 || xba.length == keyLengthBytes + 1
&& xba[0] != 0) {
throw new IllegalStateException(
"X coordinate of EC public key has wrong size");
}
if (xba.length == keyLengthBytes + 1) {
System.arraycopy(xba, 1, publicKeyEncoded, offset, keyLengthBytes);
} else {
System.arraycopy(xba, 0, publicKeyEncoded, offset + keyLengthBytes
- xba.length, xba.length);
}
offset += keyLengthBytes;
BigInteger y = pubKey.getW().getAffineY();
byte[] yba = y.toByteArray();
if (yba.length > keyLengthBytes + 1 || yba.length == keyLengthBytes + 1
&& yba[0] != 0) {
throw new IllegalStateException(
"Y coordinate of EC public key has wrong size");
}
if (yba.length == keyLengthBytes + 1) {
System.arraycopy(yba, 1, publicKeyEncoded, offset, keyLengthBytes);
} else {
System.arraycopy(yba, 0, publicKeyEncoded, offset + keyLengthBytes
- yba.length, yba.length);
}
return publicKeyEncoded;
}
public static void main(String[] args) throws Exception {
// (only) required for named curves other than those used in JCE
Security.addProvider(new BouncyCastleProvider());
// create local and remote key
KeyPairGenerator kpgen = KeyPairGenerator.getInstance("ECDH", "BC");
ECGenParameterSpec genspec = new ECGenParameterSpec("brainpoolp256r1");
kpgen.initialize(genspec);
KeyPair localKeyPair = kpgen.generateKeyPair();
KeyPair remoteKeyPair = kpgen.generateKeyPair();
// test generation
byte[] encodedRemotePublicKey = encodeECPublicKey((ECPublicKey) remoteKeyPair
.getPublic());
// test creation
ECPublicKey remoteKey = decodeECPublicKey(
((ECPublicKey) localKeyPair.getPublic()).getParams(),
encodedRemotePublicKey);
// local key agreement
KeyAgreement localKA = KeyAgreement.getInstance("ECDH");
localKA.init(localKeyPair.getPrivate());
localKA.doPhase(remoteKey, true);
byte[] localSecret = localKA.generateSecret();
// remote key agreement
KeyAgreement remoteKA = KeyAgreement.getInstance("ECDH");
remoteKA.init(remoteKeyPair.getPrivate());
remoteKA.doPhase((ECPublicKey) localKeyPair.getPublic(), true);
byte[] remoteSecret = localKA.generateSecret();
// validation
System.out.println(Arrays.equals(localSecret, remoteSecret));
}
}

Converting a string sent via SMS into RSA Public/Private key in android

I've been working on it for several days but without success, I' m doing SMS encryption in android using RSA encryption, the problem is how can I convert a String to public key and use it for encryption, I'm sending the publicKey converted into String via SMS but I'm not able to get the key back.
This is how my algorithm works but when I send "puk" as a string via Sms and make encryption it doesn't work anymore!!! plz help me . . .
private final static String RSA = "RSA";
public static PublicKey uk;
public static PrivateKey rk;
public static String puk;
public static void generateKey() throws Exception
{
KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA);
gen.initialize(128, new SecureRandom());
KeyPair keyPair = gen.generateKeyPair();
uk = keyPair.getPublic();
rk = keyPair.getPrivate();
puk = uk.toString();
}
private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception
{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text.getBytes());
}
public final static String encrypt(String text)
{
try {
return byte2hex(encrypt(text, uk));
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
public final static String decrypt(String data)
{
try{
String text = new String(decrypt(hex2byte(data.getBytes())));
return text+" OK";
}
catch (Exception e)
{
return "Error: "+e;
}
}
private static byte[] decrypt(byte[] src) throws Exception
{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, rk);
return cipher.doFinal(src);
}
public static String byte2hex(byte[] b)
{
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n ++)
{
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1)
hs += ("0" + stmp);
else
hs += stmp;
}
return hs.toUpperCase();
}
public static byte[] hex2byte(byte[] b)
{
if ((b.length % 2) != 0)
throw new IllegalArgumentException("hello");
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2)
{
String item = new String(b, n, 2);
b2[n/2] = (byte)Integer.parseInt(item, 16);
}
return b2;
}

Categories

Resources