We have to generate key hash from keystore and register it to facebook developer console.I want to understand the concept of key hash.
What benefits it provides for the server/client ?
We often see Invalid key hash error(i.e the key hash "***" does not match any stored key hashes) .So
How does my app know the correct key hash because I'm not storing it
in any xml or somewhere else?
Any kind of materials or thoughts would be appreciated.
Here Hash code is used to restrict the applications so that only valid applications (which have this particular hash code corresponds to the given certificate) can access facebook services. Because all applications are signed with particular certificates, so all the downloaded applications(say 1000 user downloads it) under same certificate must have the same hashcode and facebook is able to track which certified application used its services
We can easily find hash code of the certificate by the following code:
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.facebook.samples.hellofacebook",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
Above we are using SHA(Secure Hash Algorithm) to generate Hash code of the certificate.
SHA (Secure Hash Algorithm ) is message-digest algorithm, which takes an input message of any length and produces a 160-bit output as the message digest.
SHA is called secure because it is computationally infeasible to find a message which corresponds to a given message digest, or to find two different messages which produce the same message digest.
So before making any real request to Facebook server , first hash key
of certificate is compared with the stored hash key(i.e development
hash key or debug hash key) on the server and if they match only then
we can proceed further.
Related
I am making a demo project where integrating linkedin. In the developer site of linked in added hashkey and package but still getting {
"errorCode": "INVALID_REQUEST",
"errorMessage": "either bundle id or package name / hash are invalid, unknown, malformed"
}
Please note:i have seen many blog and question in the stackoverflow but still unable to resolve. and yes m entering correct package name and hash key.
If you have Generated a debug key hash value.
If you've added all you package hashes correctly in your LinkedIn Developer Console.
And finally you might want to save changes by clicking the blue button labelled "Update".
Test your app again
The problem is most likely your hash key, try generating it using the below code.
Try this code in your MainActivity
try {
PackageInfo info = getPackageManager().getPackageInfo("Package name",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.e("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch(PackageManager.NameNotFoundException| NoSuchAlgorithmException e) {
}
What is a key-hash, why it is needed and is it unique? Also why it is necessary for facebook integration?
My code to get the HashKey:
try{
PackageInfo info = getPackageManager().getPackageInfo("com.example.packagename",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
What is key Hash?
It's a 28 character string that Facebook uses to authenticate interactions between your app and the Facebook.
Why it is Unique?
As already mentioned in comments, It identifies your app in Facebook developer platform.
Why it is needed? Why it is necessary for Facebook Integration?
It is needed to authenticate the exchange of information between your app and the Facebook. Without this, your Facebook integration may not work properly when you release your app to the store. If you run apps that use Facebook Login then you need to add your Android development key hash to your Facebook developer profile.
For integrating your app with facebook API you will need this key. Log KeyHash will give you value which you will have to write in facebook app's setting page.
than only your application with given SHA1 code will able to access facebook api. Or you'll get authorization error. P.S: It will be unique and different for all apps and testing device and even workspace.
I have been trying to implement facebook share from my android application. I have gone through this documentation.
https://developers.facebook.com/docs/android/share.
I have successfully integrated my development key hashes for once and successfully shared to facebook from my application. The problem is when I am trying to implement the same steps for my another application. I have successfully added my key hashes and linked up my application with facebook but when I hit "POST", it is showing that Key hashes does not match and the key hash that is coming with the error message is showing the previous application's key hash.
I have double checked my key hash using this.
try {
PackageInfo info = getPackageManager().getPackageInfo(
"My Project",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(),Base64.DEFAULT));
Toast.makeText(this, Base64.encodeToString(md.digest(), Base64.DEFAULT), Toast.LENGTH_LONG).show();
}
} catch (NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
Any solution ?
That's because you have 2 Key hashes.
One for Debugging and the second is for release, when you publish your application to Google Play using a custom-made keystore instead of the Android Debug one.
Your scenario sounds like your are running your application from Eclipse/Android Studio and when you do that you are using the Debug keystore key hash which you have probably included in Facebook Developer Console already like in your previous app.
If you are exporting your APK with a different keystore you will have to get its Hash Key for this specific key store, like in the online examples you mentioned above.
I will be happy to know if you are signing your APK with debug keystore or your own. That will make things more simpler to answer.
I want to secure a Java REST backend service with two-way SSL, to prevent unauthorized access.
An Android APK needs to be signed to work, is possible to create a "trust" between my REST service and this APK, without using a hardcoded password from APK cert in client code?
The main idea is configurate the server two-way SSL to trust connections only from APK cert.
is possible to create a "trust" between my REST service and this APK, without using a hardcoded password from APK cert in client code?
Not really. Your public key in the APK is just as "hardcoded" as a password. Anyone can go in and use that information to access your REST service.
In order to perform two-way TLS/SSL you need to have a certificate with private key on the client device. The certificate used to sign the APK will result in the public key for the certificate on the device, but not the private key. You would want to avoid placing this private key on the device as it would allow others to sign APKs as you.
Instead of using the APK signing certificate for two-way TLS/SSL, you should consider using a separate certificate possibly generated per device during an initial registration process. This certificate would be installed to the Android KeyStore, and the public key from this certificate would need to be installed on the server hosting the backend REST service. This certificate would then act as client credentials in a similar manner to a username/password pair assigned to the device.
For an example using client certificates on Android see: http://chariotsolutions.com/blog/post/https-with-client-certificates-on/
I think you can try with the answer from here and use the SHA of your key that you used to sign the apk..
It says something like this:
// Add code to print out the key hash
try {
PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.e("MY KEY HASH:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
And you can save on the server side that key.. I think that is what Facebook or Google does for example..
I am creating an Android app that will integrate with Facebook. I have been able to successfully generate a Key Hash, and when I run my app to log in, I successfully got to the accept permissions button. I clicked accept and since then, I haven't been able to log back in from the app. I am given the error "(insert the key has i'm using here) does not match any allowed key. Configure your app key hashes at (lists my Facebook developer URL)". Is there any reason why a Key Hash would work and then would just stop? I did not alter any facebook settings and did not alter any application code. I've tried creating a new key hash, but that still didn't work. Any ideas on what this could be, or how to resolve it would be greatly appreciated!
I figured this out. Somehow, the Hash Key just stopped matching what I had inserted on the Facebook side. Using the facebook documentation, I added in code in my onCreate method that told me what the hash key was in my LogCat. I also added in some logging code for my catch exceptions in the event that I was screwing up my package name. This is the code:
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.your.package",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
Log.d("Error1", "NameNotFoundException");
} catch (NoSuchAlgorithmException e) {
Log.d("Error2", "Algorthim");
}
After I added that and ran it, I found the hash key in my log cat, and then just copied that to my Facebook App. Saved it, ran the app again and it worked!