ReactNativeアプリでkeystoreファイルが消えた場合の対処法

ReactNativeのアプリは最終的にはAndroidかiOS(もしくはその両方)でのリリースを目指しています。 しかし、リリースビルドというものは短いスパンでそう何回も繰り返すものではないため、久々にやってみると思いもよらないトラブルに遭遇しがちです。 今回は、Androidのリリースビルド時にkeystoreファイルが消えてしまったトラブルを紹介します。

前提条件

  • react-nativeでアプリを開発
  • Androidでリリースビルドを1回でもしたことがある

ある日のこと

仕事で開発しているReactNativeアプリで、久しぶりにAndroidのリリースビルドを行うことになりました。 ※しばらくはiOS向けに細々した機能のリリースを行っていた

手順自体は明文化されているため、特に問題らしい問題もなく、いよいよ最後のkeystoreファイルによる署名作業に移ろうとしました。

apksigner sign --ks app/my-release-key.keystore --ks-key-alias my-key-alias my-app.apk

・・・とここで謎のエラーが発生。 よくよく内容を見ていくとmy-release-key.keystoreが無くなっている。

Gitから取り直せばいいや

戸惑いつつも、ソース自体はGitlabで管理しているからkeystoreを取り直せばいいか、と思い直す(なぜkeystoreが消えたかは不明だが)。

しかし・・・

あれ?keystoreがGitになくない?

ここでちょっと解説(なぜkeystoreが必要か)

Google Play StoreAPKファイルをアップロードする際には、APKファイルに署名を行わなければなりません。 Google側はこの署名を確認して、アプリの開発元が正しいものである(=正規のAPKファイルである)と判定します。

そして、その署名に必要になってくるのがkeystoreファイル(とその中にあるalias)です。

署名はAPKファイルのビルド時に行い、そこでkeystoreファイル、aliasaliasのパスワードを使います。

今回はkeystoreファイルが何らかの原因で消失してしまったわけです。

GoogleGoogle Play App Signingという署名方法を推奨しており、今回はこの方式を採用していたのでなんとかなった、という話です。 他の方式の場合は、そもそもkeystoreを紛失したら対応不可!なんて記事も見かけます(真偽は不明ですが・・・)

なぜkeystoreは消えた?

こればかりは今今の時点で原因不明です。 先述の通り、ソースコードはGitlabで管理しているのですが、keystore.gitignoreに含まれていたため、Git管理をしていませんでした。 それ自体は決して悪いことではなく(アプリリリースに関するkeystoreを考えもなしにGitの管理下に置くのはそれはそれでリスクがある)、ファイルサーバ等に置いて管理しているケースもあるようです。 いずれにせよ、今回は自端末(それも開発機として頻繁にソースをいじる)にしかリリース用のkeystoreを置いておらず、管理をしていないことが原因でした。

※ちなみに、この反省を受けて現在はGitlabで管理しています。プロジェクトに関わるメンバなら見れてしまいますが、担当しかaliasのパスワードが分からないので大丈夫、という認識です。 もっと良い管理方法をご存じの方がいらっしゃいましたらコメントにてお教えください。

復旧手順

ざっくり説明すると、新規にkeystoreファイルを作成し、pemファイルを作成。 作成したpemファイルをGoogle Play Consoleからアップロードしてアップロード用鍵のリセットを申請した。ということです。

keystoreを再生成

下記のコマンドを入力し、いくつかの質問に答えるとkeystoreファイルが生成されます。最後にパスワードを聞かれるので登録する。

keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

pemファイルを生成

下記のコマンドを入力し、keystore生成時のパスワードを入力すると、pemファイルが生成されます。

keytool -export -rfc -alias my-key-alias -file my-release-key.pem -keystore my-release-key.keystore

なぜpemファイルを生成するのか

これは先にちらっと出てきたGoogle Play App Signingに関連しています。 Google Play App Signingをざっくり説明すると、Googleに対してリリース用鍵を渡し、APKファイルをビルドする際はアップロード用鍵で署名する方式です。 この方式のポイントは、リリース用鍵を管理しなくともよく、リリースする側(APKをアップロードする側)はアップロード用鍵だけを管理すればよいということです。 アップロード用鍵は再登録できる(とはいても簡単にはできない)ので紛失しても安心、というわけです。 つまり、ここで生成したpemファイルは新たなリリース用鍵で、keystoreアップロード用鍵です。

Googleにpemをアップロード

Google Play Consoleで対象アプリを開いたら[リリース管理][アプリの署名]を開き、[鍵のアップグレードをリクエスト]をクリック。

事由を聞かれるので、 [各リリースの署名に使用しているアップロード鍵を紛失したため]を選択し[次へ]を押下

keystore2

サポートに問い合わせてほしい旨のメッセージが表示されるので、[サポートにお問合せ]を押下。

問い合わせ画面が表示されるので、各種アプリ情報を入力して[鍵またはキーストアに関連する問題がある]を選択。 続いて[アップロード鍵を忘れた]を選択し、詳細を記入(下図参照)。 最後にpemファイルを添付して[送信]を実行。

keystore1

数日経つとGoogleから登録していたアドレス宛にメールが届きます。 内容をかみ砕くと、

  • 新しい鍵の登録が完了したで
  • YYYY-mm-ddから利用可能や
  • 今度からは気を付けるんやで(意訳)

といった旨です。 実際に指定された日時以降は、新しいkeystoreファイルで署名をしたAPKファイルがリリースできるようになりました!

まとめと反省

反省点としては、keystoreの管理方法が杜撰だったの一言に尽きます。 これは何もkeystoreだからという話に限らず、アプリやプロジェクトのコアとなる大事そうなファイルバックアップを取るバージョン管理をするなどが重要です(初歩中の初歩ですが、今回は実際それができていなかった)。

なんにせよreact-nativeのプロジェクトでは、デフォルトの.gitignore.keystoreを含めてあめ、今回と同じ事象に遭遇する方は少なからずいると思います。 その場合の一助になれば幸いです。

SNSでシェアする