What’s keytool, why can’t it be found, and why does Firebase even want a “SHA-1”?

Patrick Martin
Firebase Developers
5 min readMar 6, 2020

If you’ve followed any of the Firebase tutorials for Android, you probably came across an instruction like “Add the SHA-1 hash for your project.” You may have even been linked to this page, where you were told to type keytool -list -v followed by a strange symbols involving -keystore.

Now for many developers, including most Google employees with the standard dev tools, this just works and we don’t question it. Others will get one of these super exciting error messages:

keytools: command not found

'keytool' is not recognized as an internal or external command

This is also an optional step for many of Firebase’s products. Currently Firebase Dynamic Links and some Firebase Authentication products (such as Google Authentication and Phone Authentication) are the only products that need a SHA-1.

What is “keytool”?

Whenever I need to figure out what a command does, I search for man <command_name>. My first result is Oracle’s documentation saying:

Manages a keystore (database) of cryptographic keys, X.509 certificate chains, and trusted certificates.

That’s a really cool one liner, but what you need to know is that it generates a file (called a “keystore”) that can be used to “sign” an Android application. This signature is used to verify authenticity. The really cool thing here is that it’s practically impossible to fake a signature without stealing the keystore file, but you can publish a “fingerprint” of your signature so anyone can validate the signature on their own.

Ok, where is it?

keytool is a standard program that ships with the Java Development Kit (JDK) or runtime (JRE). Both Oracle’s JDK and OpenJDK ship with it, and on MacOS and Linux it’s usually simple enough to just install the JDK and call it a day.

On Windows or complex environments, you’ll want to look in the /bin directory of the JDK. You can either invoke it directly by typing this full path, or add it to your system’s $PATH environment variable.

I already installed Android Studio, do you mean I have to install Java too?

Nope!

keytool ships with a standard Android Studio install as part of the JRE needed to run Android Studio itself. If you look at where you installed Android Studio (usually C:\Program Files\Android\Android Studio on Windows or /Applications/Android Studio on Mac), you’ll find a folder inside called jre. You’ll be able to find the keytool command there.

Helpful hint: you can drag/drop this keytool application to get its full path in your terminal on MacOS, Windows 10, and most standard Linux distributions!

gif showing the keytool command being dragged from Finder to iTerm2, then having the parameters `-list -v -alias androiddebugkey -keystore ~/.android/debug.keystore` added.

I installed the Android SDK with Unity, do you mean that I need to install the JDK or Android Studio to use Firebase?

Nope!

If you navigate to your Unity installation, you should see keytool under PlaybackEngines/AndroidPlayer/OpenJDK. Once again, you can drag and drop this into a terminal as demonstrated above or you can add this to your $PATH if you feel so inclined.

debug.keystore doesn’t exist!

If you’ve gone through all of this, enter the appropriate command line, and you get a new message saying:

keytool error: java.lang.Exception: Keystore file does not exist:

All you have to do is perform a full Android build. debug.keystore will be auto-generated the first time you make an Android device build of an application.

If you want to look for the debug.keystore on your own, this is usually stored in a hidden folder named .android in your user home directory. You can type into a terminalls ~/.android/debug.keystore on Linux and MacOS or dir %USERPROFILE%\.android\debug.keystore on Windows to find it.

This sounds cool, but what’s the SHA-1 and why does Firebase care?

The act of signing an application doesn’t have any intrinsic value without some way of verifying the identity of the signer. This is what the SHA-1 fingerprint provides, you can pull the SHA-1 out of a signed Android game or application and check it against some central point of authority to ensure the signature itself was valid. But who is the authority for something that lives on a local development machine?

When an application talks to Firebase, Firebase should only consider the application legitimate if its SHA-1 corresponds to one you have listed in the Firebase Console for your application. This means that Firebase itself acts as an authority and can tell that an incoming application looks like one that you’ve made.

When your application tries to use any Firebase service on Android, Firebase’s servers confirm that two things are true:

  1. the application ID matches one of the applications in your project.
  2. the SHA-1 of of the signed game or application matches a SHA-1 that the developer uploaded to the Firebase project’s console.

This has an interesting side effect that a combination of package id and the SHA-1 are used to match a game or application with a Firebase project. Because of this, you cannot have two Firebase projects that contain the same package id and signing signature. It is expected that you’ll use the same development SHA-1 across many projects, but if you ever see An OAuth2 client already exists for this package name and SHA-1 in another project, you’ll want to ensure that your package name is unique.

Wrap Up

Go ahead and finish setting up Firebase with Android, Unity, or whatever else you needed a keytool to unlock. And don’t forget to run through this checklist when you’re ready to ship. You’ll probably see keytool surface once again when you’re ready to sign a release build.

Resources

--

--

Patrick Martin
Firebase Developers

I’ve been a software engineer on everything from games to connected toys. I’m now a developer advocate for Google’s Firebase.