The unfortunate challenge in signing a new app to release on Google Play in Nov of 2021
Published: 2021-11-19 21:20:16

I'm trying to deploy an app to Google Play and it's been challenging.

First I'm greeted with this page. [Wojtek Kaliciński](https://twitter.com/wkalic) has a [video](https://www.youtube.com/watch?v=odv_1fxt9BI) on this and it was amazingly helpful in deciding the right choice for me. **I wish this video was linked on the play console** :smile:

![App Signing Preferences Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhmzm0tp2mzru9ef4esk.png)
 
My choice is to go with "Export and upload a key from Java keystore".

![My Choice](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05y7fl5a1j3zts43pa9e.png)

Next, I went to download the PEPK tool, but was greeted with this 404 page. After ~~complaining~~ notifying @googleplay, @googleplaydev and Wojtek about it on Twitter... Wojtek got back to me first to tell me it was fixed. Hooray Wojtek and developer relations!

![404 on PEPK jar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hjzaapxy1ed0rmpm1x6g.png)
 
Now that I actually have the pepk.jar I stumbled a bit more unfortunately. Firstly, I went to create the keystore.

I had a few problems with this dialog and overall I feel like it should get some attention from the AS team. First is when you try to choose a keystore path, it just creates a file with no extension. This is weird to me because I (think) that the file should be a .jks extension(but what do I know)? I don't actually know for sure if it's important, but it feels weird that the wizard doesn't default to it.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pu5cclletz1k9uu013jq.png)

**Update**: Wojtek said "the extension of the keystore doesn't really matter, that said on Linux it did create .jks for me" With that said, I'm going to always use .jks as that shows me what the intent of the file is. I do wish that they just used .jks everywhere instead of jumping between a bunch of different name schemes.

The next issue is adding a password. Following the [docs](https://developer.android.com/studio/publish/app-signing): 

> Create and confirm a secure password for your key. This should be different from the password you chose for your keystore.

If you actually try to put a different password for the keystore and the alias you're greeted with this.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/15e27emgp5mb50jgc5by.png)

As a non-expert in security... I don't know what the hell is going on. I suppose that I'll just try to create the keystore and alias with the same password.

Someone should file a bug for that. Oh right! I [did](https://issuetracker.google.com/issues/197945015) a few months back.

Okay... so I have a keystore... now it's time to run the pepk command we saw at the top!

> Run the tool using the command below to export and encrypt your private key. Replace the arguments, and enter your keystore and key passwords when prompted.
 
Okay... so I have to replace the bolded text...

--keystore=**foo.keystore** --alias=**foo** --output=**output.zip**

Okay... so I'm having this jks "issue" again? Is it .jks or is it .keystore or does it not have an ext at all? The alias (I think) should just be key0 (I left it as the default alias name in the AS keystore generation wizard) and the output.zip name seems fine.

Okay... so I will now run this command. Note that I added the extension .jks to the `prod` file that was generated.

```
$ java -jar pepk.jar --keystore=prod.jks --alias=key0 --output=output.zip --include-cert --encryptionkey=abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123
```

**Another error!**

```
Error: No value provided for flag: include-cert
USAGE:
       java -jar pepk.jar --keystore <release_keystore> --alias <key_alias> --encryptionkey=<encryption_key_hex> --output=<output_file>
```

Okay... so now I'm lost again. Is include-cert needed or not?

For now... let's just drop that flag and see what happens.

```
$ java -jar pepk.jar --keystore=prod.jks --alias=key0 --output=output.zip --encryptionkey=abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123
```

**Update**: The problem was that I was using Java 15. I downloaded a Java 11 jar and used that instead and everything worked! I [filed a bug](https://issuetracker.google.com/issues/207325146) to update pepk tool, or to add a warning that the pepk tool only works with (presumably) Java 11 and lower.

It asks me for the `store` password and then a `key` password. Now I'm starting to feel really bad that I created both store and key with the same password. The docs said to use a different password too. Oh well. I'll accept the risk I suppose.


Hooray! I think we're getting somewhere! `output.zip` was generated!

One last step! Wojtek's video said that it's recommended to create a new upload key. Let's do that!

The screenshot above says "For increased security, create a new upload key (optional)." so it sounds like I'll want it!

All I need is a single command, and replace the bolded keywords...

keytool -export -rfc -keystore **upload-keystore.jks** -alias **upload** -file **upload_certificate.pem**

Okay. Now I'm confused again... It's talking about an upload-keystore.jks... is this different than the foo.keystore they were talking about? I don't know... but I'm going to assume that it's actually the same keystore. All this time... I'm still confused if I should be using `prod`, `prod-keystore` or `prod.jks`. Someone send help!!!

Okay. What's the alias? `upload`? Should I use `key0`? Send more help!!!

The command I ended up with is

```
keytool -export -rfc -keystore prod.jks -alias key0 -file upload_certificate.pem
```

As you can hopefully tell... I opted not to create a new keystore in the AS wizard... I just used the keystore I already created and I'm assuming that it'll create the upload key from that.

**Update**: As per Wojtek, you should be using a new key/alias or a new keystore entirely.

"You can run it again and generate a new keystore with a new key. A keystore can contain multiple keys, but it might be easier to just  keep them separate. A keystore is just a file container for keys" -Wojtek

"it" in the context above is the "AS keystore generation wizard"

# Upload time!

I upload the generated zip... and the key certificate... and...

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/947dnc1x6tf9psampdzk.png)

# @!&#%@

**I give up** (for now). If someone from the Play Console or Android Studio team in general read this... please send help. :sweat-smile:

# Update! It works!
With some help on Twitter from Wojtek I was able to figure everything out.

The gist of it is:
1. The pepk tool is no longer 404'ing
2. The pepk tool doesn't work with Java 15, but worked with Java 11.
3. The docs still say to use a different password for the keystore and alias, but it seems that using the same one is fine
4. To use the additional security of an upload key, you can just generate another keystore + alias combo for uploading.
5. At the end of these steps you'll have a
 - `app-signing.jks` that Google will use to sign your app, and you can use this for other stores/dist methods. Never lose this.
 - `app-upload.jks` is what you will use to sign your app when uploading to google play, and google will then use the `app-signing.jks` to sign on your behalf. If this upload key is lost or falls into the wrong hands, you can request a new one!
 - `output.zip` which is the output of the pepk command. After you upload this, you are safe to delete it. It is only necessary in order to give google your encrypted private key.
 - `upload.pem` is your public key that you give google so they know when they receive a valid app upload that was signed with your private key. You are safe to delete this as well after you upload it.