発生した事象
Windows用のExeをElectronでリリースしサービス開始から1年近くが過ぎたある日のこと。
コードサイニング証明書の期限切れが近づいているので、新たに取得した証明書でビルドを行うことに。
初めての証明書変更だったが、electron-builderでビルドしelectron-updaterを使用しているので、なんとなくうまくやってくれると思っていた。。。
「自動更新ができないんだけど・・・」
新しい証明書でビルドした際はエラーがなく、ローカル端末でパッケージをインストールし実行できることを確認。
ステージングでの検証を通過しいよいよ本番。(後から振り返れば、ステージングを通過していることがおかしいのだが、検証方法に問題があった)
リリース直後、担当から呼ばれてかけられた言葉がそれだった
そもそもコードサイニング証明書とは
コードサイニング証明書はソフトウェアが改ざんされず作成元で生成されたものを保証する。
大まかに以下のようになっている
1.コード、暗号化されたハッシュ値(デジタル署名)、コードサイニング証明書を使ってパッケージを作成
2.コードサイニング証明書の有効性の確認
3.コードサイニング証明書に含まれる公開鍵の取得
4.暗号化されたハッシュ値(デジタル署名)を公開鍵で復号し証明書に含まれているハッシュ値を取得比較
ハッシュ値が一致すれば改ざんによる不正がないパッケージであることが証明される
証明書の期限切れとはどういうこと
私自身勘違いしていたが、例えば、証明書の期限が2020年12月31日までだとする。
2021年1月10日に上記期限で作成されたパッケージはインストールできないのか?
そうではない。
証明書を使うパッケージ作成時に証明書の期限チェックを行うので、ビルド時に期限内であればよい。
どうやらSSL証明書と混同していたようだ(;'∀')
今回の事象の原因究明
話を今回の事象に戻そう。
自動更新ができないためエラーログを見たところ、electron-updaterのチェックでパッケージが異なると判定されていた。
実は今回、Aの発行者からBの発行者に変更していて、Aの発行者では半角英数字の発行先にしていたが、Bの発行者に変更した際日本語の発行先を設定した。
これが影響して発行者のチェックではじかれたのが原因だ。
通常発行者が変更することは少ないが、カナ登録の発行先がある場合は同様のことが発生するため、electron-updaterのチェック仕様についてまとめた。
electron-updaterの更新チェック処理の概要
1.インストール済みのパッケージ起動
2.ダウンロード先に配置されたパッケージのバージョンをチェック
3.インストールより新しいバージョンがあれば、ローカルのtempフォルダ内に最新版をダウンロードして証明書チェック
4.証明書チェックOKであれば、tempフォルダにダウンロードしたパッケージをインストール
チェックエラーであれば、tempフォアるだを削除しインストールエラーとする
証明書チェックについて
electron-updaterのverifySignature内で実行される。
以下のpowershellのコマンド「Get-AuthenticodeSignature」にて取得したSignerCertificate.Subjectをbase64ででコードし、urf8に変換する。
execFile("powershell.exe", ["-NoProfile", "-NonInteractive", "-InputFormat", "None", "-Command", Get-AuthenticodeSignature '${tempUpdateFile}' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
], {
timeout: 20 * 1000
}, (error, pro, stderr) => {
実はこの処理に問題があった
verifySignatureの以下の処理を実行し、取得した文字列とインストール済みのパッケージのpublishNameを文字列比較し署名が正しいかを判定している。
const data = parseOut(Buffer.from(stdout, "base64").toString("utf-8"))
その際、カナ文字の変換では正しく変換されず、発行先が異なると判定され証明書チェックエラーとなっていた。
ホントにそれでいいのか。。。
結論
すでにリリース済みで、インストールされたものを回収できないため、今のelectron-updaterでチェックを通すために、発行先を半角英数字で登録した証明書を使うことにした。
今回Electronを使ってみてパッケージ作成の選択肢の一つになると思った。
パッケージの自動更新やコードサイニングなどについては改善点があるとも感じている。