I am building an Android application that needs to keep track of some of the other applications installed on the device.
For a given application (package) I need to compute a hash values such that:
The value is different for different versions of the same application
The value is the same for the same version of the same application installed on different devices
Is there a way of doing this efficiently?
Thank you
Simply load the apk as a file and compute the MD5 hash of the file with:
public String md5(String s) {
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
Taken from: http://www.androidsnippets.com/create-a-md5-hash-and-dump-as-a-hex-string
Update:
Are you simply trying to see if a newer version of an App has been installed why not use the PackageManager.getPackageInfo method? It returns a PackageInfo object that contains the version number of the application. You can track these values and when they change it means that an app has been updated. See this: http://developer.android.com/reference/android/content/pm/PackageManager.html
Related
I am trying integrate PayUmoney android SDK in my application,i integrate successfully But i face one problem.
in test mode they provide url to generate hask key but live they wont provide
Test mode: https://test.payumoney.com/payment/op/calculateHashForTest
For Live Mode:???
i am trying below Code to generate Live Hash key
String salt="saltkey";
String hashSequence=key+"|"+txnid+"|"+amount+"|"+productinfo+"|"
+firstname+"|"+email+"|"+""+"|"+"|"+""+"|"+""+"|"+""+"|"+salt;
String serverCalculatedHash= hashCal("SHA-512", hashSequence);
paymentParam.setMerchantHash(serverCalculatedHash);
PayUmoneySdkInitilizer.startPaymentActivityForResult((Activity)
context, paymentParam);
BUt i got below response from sdk
{"status":-1,"message":"key is not valid","result":null,"errorCode":null,"responseCode":null}
{"status":-1,"message":"payment status for :1111322345","result":"PP1 not updated till now from P2","errorCode":null,"responseCode":null}
please give solution to:
1. generate live hash key using url,
2.why above mention response return from PayUMoney SDk
Expecting your valuble answer.
You can use this function for generate Live hash key for PayUMoney android
public static String hashCal(String type, String str) {
byte[] hashseq = str.getBytes();
StringBuffer hexString = new StringBuffer();
try {
MessageDigest algorithm = MessageDigest.getInstance(type);
algorithm.reset();
algorithm.update(hashseq);
byte messageDigest[] = algorithm.digest();
for (int i = 0; i<messageDigest.length; i++) {
String hex = Integer.toHexString(0xFF &messageDigest[i]);
if (hex.length() == 1) {
hexString.append("0");
}
hexString.append(hex);
}
} catch (NoSuchAlgorithmException nsae) {
}
return hexString.toString();
}
And call like
String serverCalculatedHash = hashCal("SHA-512",MERCHANT_KEY+"|"+txnId+"|"+Double.parseDouble(totalPrices)+"|"+productName+"|"
+userName+"|"+userEmail+"|"+udf1+"|"+udf2+"|"+udf3+"|"+udf4+"|"+udf5+"|"+MERCHANT_SALT);
serverCalculatedHash contain hash key for PayUMoney
Check your payu dashboard at Integration Credentials: Merchant Key and Merchant Salt will be available.
Also check the .setIsDebug(true) // For Integration environment - true, For Production - false.
You specified that Hash
String hashSequence=key+"|"+txnid+"|"+amount+"|"+productinfo+"|"+firstname+"|"+email+"|"+""+"|"+"|"+""+"|"+""+"|"+""+"|"+salt;
It should be :
hashSequence=key+"|"+txnid+"|"+amount+"|"+productinfo+"|"+firstname+"|"+email+"|"+udf1+"|"+udf2+"|"+udf3+"|"+udf4+"|"+udf5+"|"+udf6+"|"+udf7+"|"+udf8+"|"+udf9+"|"+udf10+"|"+salt;
user define string can be empty, but it has to passed in hash sequence.
I want to save some of my sensitive data (string) in keyStore. I found that keyStore only accepts secretKey objects. But, I'm not able to store it and and retreive it later using keyChain callback by using the alias name of the secretKey
Any help will be appreciated..!
I think you are looking something like MD5. An MD5 hash is created by taking a string of an any length and encoding it into a 128-bit fingerprint. Encoding the same string using the MD5 algorithm will always result in the same 128-bit hash output. MD5 hashes are commonly used with smaller strings when storing passwords, credit card numbers or other sensitive data in databases such as the popular MySQL. This tool provides a quick and easy way to encode an MD5 hash from a simple string of up to 256 characters in length.
MD5 hashes are also used to ensure the data integrity of files. Because the MD5 hash algorithm always produces the same output for the same given input, users can compare a hash of the source file with a newly created hash of the destination file to check that it is intact and unmodified.
Hashing String with MD5:
public class JavaMD5Hash {
public static void main(String[] args) {
String password = "MyPassword123";
System.out.println("MD5 in hex: " + md5(password));
System.out.println("MD5 in hex: " + md5(null));
//= d41d8cd98f00b204e9800998ecf8427e
System.out.println("MD5 in hex: "
+ md5("The quick brown fox jumps over the lazy dog"));
//= 9e107d9d372bb6826bd81d3542a419d6
}
public static String md5(String input) {
String md5 = null;
if(null == input) return null;
try {
//Create MessageDigest object for MD5
MessageDigest digest = MessageDigest.getInstance("MD5");
//Update input string in message digest
digest.update(input.getBytes(), 0, input.length());
//Converts message digest value in base 16 (hex)
md5 = new BigInteger(1, digest.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}
}
referance :
http://viralpatel.net/blogs/java-md5-hashing-salting-password/
https://www.mkyong.com/java/java-md5-hashing-example/
http://www.asjava.com/core-java/java-md5-example/
you can use shared preferance which is very easy to handle also.
https://developer.android.com/training/basics/data-storage/shared-preferences.html
Android Shared preferences example
I am working on mobile product. We are using the data in xml document. In order to keep our data secure we need an encryption algorithm(but we don't want the existing algorithm to import)
Can u give me some steps to encrypt the data.(if code example is most welcome).
To be more secure, you have to do with your own secret key. Try to use this code
KeyStore ks = KeyStore.getInstance();
// get the names of all keys created by our app
String[] keyNames = ks.saw("");
// store a symmetric key in the keystore
SecretKey key = Crypto.generateKey();
boolean success = ks.put("secretKey1", key.getEncoded());
// check if operation succeeded and get error code if not
if (!success) {
int errorCode = ks.getLastError();
throw new RuntimeException("Keystore error: " + errorCode);
}
// get a key from the keystore
byte[] keyBytes = ks.get("secretKey1");
SecretKey key = new SecretKeySpec(keyBytes, "AES");
// delete a key
boolean success = ks.delete("secretKey1");
If you want to develop your own encryption scheme, be prepared to embark on a research project. You can use any of standard encryption algorithms like AES/DES etc, with your private keys that are sufficiently long and difficult to crack.
public string PassEncrypt(string Password)
{
// Encrypting the password entered by User
// ======================================================
MD5 md5 = new MD5CryptoServiceProvider();
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(Password));
byte[] result = md5.Hash;
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
strBuilder.Append(result[i].ToString("x2"));
}
return strBuilder.ToString();
// ======================================================
}
OR
You may refer on this links :
developer.motorala.com
codereview.stackexchange.com
android snippets
java-tips.org
What is the Hash of Test Device ID by AdMob?
I have the Device Number. But not the Hash and i will Hashing the number.
It uses an md5 hash, but it may also have a SALT.
The best way to get the hashed device ID is to check the logcat output when you make an Ad Request on a device. You'll get a message to the effect of:
To get test ads on this device, call adRequest.addTestDevice("0123456789ABCDEF");
That string is your hashed device ID that you can add to your app.
It is NOT RECOMMENDED to try to craft this hashed device ID yourself. If you get the device's ID and hash it to get test ads, but forget to remove that code when you release your app, all of your users will get test ads and you'll make no money. The current mechanism is intended to try and prevent you from making this mistake.
use md5 for getting hash id
here is a procedure
public static final String md5(final String s) {
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest
.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String h = Integer.toHexString(0xFF & messageDigest[i]);
while (h.length() < 2)
h = "0" + h;
hexString.append(h);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
Logger.logStackTrace(TAG,e);
}
return "";
}
another way to get the hash id is installing
Admob test device id app
If someone tampers with an installed android app (apk file), are there any checks done at the time of launching to ensure integrity of an app is not compromised? As I understand there are no checks performed at launch time and I am trying to do the following:
I am trying to compute SHA-1 digests of the installed applications (apk file). I am aware that an apk file is like a zip file. It consists of other files. However, I am treating it as any other file (just a stream of bytes) and trying to compute SHA-1 digests of all the apk files. Are there any problems with this approach? The following code kept on giving null exception:
private static byte[] getSHA1FromFileContent(String filename)
{
try
{
MessageDigest digest = MessageDigest.getInstance("SHA-1");
//byte[] buffer = new byte[65536]; //created at start.
final FileInputStream fis = new FileInputStream(filename);
int n = 0;
byte[] buffer = null;
while (n != -1)
{
n = fis.read(buffer);
if (n > 0)
{
digest.update(buffer, 0, n);
}
}
byte[] digestResult = digest.digest();
return digestResult;
}
catch (Exception e)
{
return null;
}
}
As an alternative when I attempted to retrieve the files from the apk file and save the individual files as follows, I again kept on null exception
public void unzip()
{
try
{
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null)
{
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
File dstfile = new File(_location + ze.getName());
dstfile.createNewFile();
FileOutputStream fout = new FileOutputStream(dstfile.getPath());
//OutputStream out = openFileOutput(_location + ze.getName(), Context.MODE_PRIVATE);
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
}
catch(Exception e)
{
Log.e("Decompress", "unzip", e);
}
}
I am also verifying the application configuration by way of - PreferencesManager.getDefaultSharedPreferences call providing the package name of the application as input parameter
In order to verify the integrity of an installed application is the above check enough?
If someone tampers with an installed android app (apk file), are there any checks done at the time of launching to ensure integrity of an app is not compromised?
There is no such concept as "compromised" from the OS standpoint, other than having an invalid digital signature. If somebody tampers with your app and signs it, that is indistinguishable to the OS from your original app, or the app after Amazon "tampers" with it for their store, etc.
Are there any problems with this approach? The following code kept on giving null exception
First, you are handling exceptions and doing no logging. You will find that debugging is much simpler when you log your exceptions. Then, you can use the stack trace (e.g., from DDMS) to find the line on which you are crashing, and fix your bug, whatever it is. If you want help with that, you will need to include in your question details on where the NullPointerException is occurring.
Second, whoever tampers with your app will simply remove all of this code, if they can find it.
Third, it may be fairly slow, making it easier for them to find it.
I am also verifying the application configuration by way of - PreferencesManager.getDefaultSharedPreferences call providing the package name of the application as input parameter
I have no idea why you think that this will be some form of verification.
In order to verify the integrity of an installed application is the above check enough?
IMHO, the above check is largely useless. If you obfuscate your code (e.g., with ProGuard), call it from several places, and use the other techniques outlined in this blog post, perhaps it will be worthwhile, but it may be too slow.