I am developing an Android library which I am going to distribute to my business partners. I have signed it with my key store and I want to verify the signature on runtime to see if my library is recompiled using a different signature. But the normal way to verify the signature
PackageManager pm = ctx.getPackageManager();
(PackageInfo packageInfo = pm.getPackageInfo(ctx.getPackageName(),
PackageManager.GET_SIGNATURES);)
in case of APK is not working as it returns only the application's signature and not the signature I signed my library with. Is there a way to do this?
Related
The PackageManager.getPackageInfo(packageName, flags) method can be used to check whether a specific package has been installed. It either returns the PackageInfo or throws PackageManager.NameNotFoundException.
How to check if a library APK is installed? An example of the library APK is Trichrome Library: https://www.apkmirror.com/apk/google-inc/trichrome-library/trichrome-library-98-0-4758-101-release/trichrome-library-98-0-4758-101-3-android-apk-download/download/
After installation of this APK, calling PackageManager.getPackageInfo('com.google.android.trichromelibrary', 0) throws PackageManager.NameNotFoundException.
Looking via ADB, I see that once installed, it's not visible under pm list packages but it's visible under pm list libraries with the name "library:com.google.android.trichromelibrary".
Is there any way to determine programmatically whether the library has been installed?
As you can see in the source code of pm in this link, pm list libraries command uses PackageManager.getSystemSharedLibraryNames() which is documented here.
If this method is not working, there are also other methods in PackageManager to get info about shared libraries. As mentioned by #vmayorow, One of these methods is PackageManager.getSharedLibraries(0).
Am trying to find a way to get SHA256 of a mobile app,i have search around but i didn't understand some of the things i came across. i tried
MessageDigest md = MessageDigest.getInstance("SHA");
try {
md.update(toChapter1);
MessageDigest tc1 = md.clone();
byte[] toChapter1Digest = tc1.digest();
md.update(toChapter2);
...etc.
} catch (CloneNotSupportedException cnse) {
throw new DigestException("couldn't make digest of partial content");
}
and also if you can explain the concept i will be glad
To access APIs in Android from Google API console you need to generate an API Key. This same API key can be used for accessing multiple APIs under the same project. To generate an API key you require, SHA1 fingerprint of your keystore. Keystore is basically a place where the private keys for your app are kept. In simple words its a certificate generated by a user or a program, used for signing an Android app.
In Android, there are two types of keystores. A debug keystore and a release keystore. Debug keystore is generated automatically when the Android SDK is installed or run for the first time. Release keystore has to be generated manually by the user for each application before release. As it requires private information such as name, password etc. To obtain an Android SHA1 fingerprint from your desired keystore.
i found a Hashing Library at android arsenal and its very easy,simple and just one line of code. can hash MD5, SHA-1, SHA-256, SHA-384, or SHA-512.
1.first add this to your gradle and sync
implementation 'com.github.1AboveAll:Hasher:1.2'
Start hashing...
Hasher.Companion.hash("Hello",HashType.SHA_1);
I inherited an android app that was initially outsourced to an external developer, fixed stuff and I am now ready to send the new update to the play store.
Then I found out that I need a specific signing key in order to update the app, which we got from the previous developer.
So I generated a signed release apk using the key I got and tried to upload. Upon uploading, I get a pop-up with an error. see screenshot for details
We asked the developer if he was sure that was the key he used, and he swears he looked everywhere and its the only key he used. Although, I do think he might have changed the password for it..., not really sure.
Significant changes I introduced to the app is changing the package in manifest and creating product flavours which each their own package name(one of them got to keep the original package name from the play store).
Some things I noticed: When I got the app, the app manifest had an out-commented package name and a new one with our company's name in it. The original one had the name of the of the outsourcing company in place of the "example" of the "com.example.appname" bit, so they must have changed the package name when they created the release apk.
I have no idea if any of this means anything because the package name is the same when I put it all in an apk... It's just that the store claims that the app was signed with a different certificate and the previous developer swears he used the same he sent to us.
Can anyone tell me if it's possible to do anything to make this work, or are we completely doomed and will have to upload a new app to the store?
Thanks for any help.
Update:
Because people are asking about packagename, let me clarify.
When I got the app, all the packagenames in the manifest was not the same as the one from Playstore... so i refactored the entire package app-wide to reflect the play-store package name... and then I introduced product flavours because we need a new app with different branding that is similar to the original one... so I ended with with a structure like this:
defaultConfig {
applicationId "PlayStorePackagName"
}
productFlavors {
brand1 {
applicationId "PlayStorePackagName" //<- for original app
}
new_brand{
applicationId "NewPlayStorePackagName" //<- for new app.
}
}
In this case, it shouldn't matter what package name is in the manifest, should it?
You cannot change the package name nor the Certificate for the App for the Playstore! If you don't have the correct certificate you cannot submit your App as an update to the existing one.
Certificate checking
However you can check the information stored in your available Keystore and compare it with the current store apk. For Example:
jarsigner -verify -verbose -certs yourapp.apk
You can get more details with the keytool. See this Thread for more information.
Package name
You can check the correct package name for your app when Browsing to your App in the play store.
Example for Google Plus: https://play.google.com/store/apps/details?id=com.google.android.apps.plus
id=com.google.android.apps.plus is the package name in this case. This cannot be changed for your App
However this package name is defined by your applicationId within your App. Your structure of your app can have different package names. See here for more information.
From the docs:
When you're ready to make changes to your APK, make sure to update your app’s Version Code as well so that existing users will receive your update.
Use the following checklist to make sure your new APK is ready to update your existing users:
The Package Name of the updated APK needs to be the same as the current version.
The Version Code needs to be greater than that current version. Learn more about versioning your applications.
The updated APK needs to be signed with the same signature as the current version.
To verify that your APK is using the same certification as the previous version, you can run the following command on both APKs and compare the results:
$ jarsigner -verify -verbose -certs my_application.apk
If the results are identical, you’re using the same key and are ready to continue. If the results are different, you will need to re-sign the APK with the correct key.
You say that:
Significant changes I introduced to the app is changing the package in manifest
So this is the source of issue. You'll need to use the same package name.
We have a third party app that has been created for us, but that we will maintain going forward.
They have built the apk and signed it with their own key, but in order for us to upload it and to use our key I have had to resign it.
For this I used https://code.google.com/p/apk-resigner/
Now I'm trying to compare their apk with my resigned one, but am not 100% sure what to do.
I've tried doing
jarsigner -verify -keystore my_keystore_location -verbose -certs my.apk
and i've received lots of files with smk on them. This would make sense following the key
s = signature was verified
m = entry is listed in manifest
k = at least one certificate was found in keystore
i = at least one certificate was found in identity scope
but then when I run the third party apk that still has their key, I also get smk on the files, which shouldn't happen as that would say it has been signed with a key in my keystore!?
Any ideas anyone?
Thanks
I'm not exactly sure if this works but I spotted it in package manager :
http://developer.android.com/reference/android/content/pm/PackageManager.html#checkSignatures(java.lang.String, java.lang.String)
Its supposed to be able to take your first package(your own)'s signature and compare it with your third party app's signature. This is ran on the android app and not on your development platform(Windows, Mac, Linux etc).
Looking at the documentation, if 0 is returned, the signature matches. If 1 is returned, neither are signed. -3 for no match. -2 for not second package not signed and -1 for first package not signed. -4 if either packages are invalid.
This code is working for me :
final PackageManager pm = getPackageManager();
System.out.println(pm.checkSignatures("com.testing1", "com.testing2"));
Are there any libraries or API about Graphometric Signature for Android? I need to integrate to my Android app a (biometric) graphometric signature system. Grafometric sisgnature is only valid legal signature.
you can try Namirial S.p.A. solution.
http://www.graphosign.com/
http://www.firmagrafometrica.it/
You can use the Namirial solution with Windows, Android & iOs.
They also provide an sdk for the all platform.
For more information you can send an email to: info#graphosign.com