Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What is going on with this article?
@umamichi

Mac OS で Electron の autoUpdate をするために証明書をとってリリースする方法

More than 1 year has passed since last update.

まずは、証明書について

コードサイニング証明書って?

オンラインで配布するソフトウェアにデジタル署名を行う電子署名用の証明書

👆コードサイニング証明書で署名されていないソフトウェアは改ざんを受けている可能性があるため、インストール時に警告が表示される

デジタル署名を行うメリット

  • ソフトウェアの開発元・配布元を明確に証明
  • なりすまし、内容の改ざんされていないことを保証
  • 正規の配布元であることを証明することにより、ソフトウェアのインストール率増加

デジタル署名がされていないソフトウェアのリスク

  • 配布元のなりすまし
  • プログラムが改ざんされている
  • マルウェア(ウイルス)が仕込まれている

署名と検証の仕組み

署名(開発側の処理)

  1. コードサイニング証明書取得
  2. オリジナルコード(=ソフトウェアのプログラムデータ)から、ハッシュ値を生成
  3. コードサイニング証明書の秘密鍵でハッシュ値を暗号化 👈これがデジタル署名
  4. オリジナルコード, 暗号化されたハッシュ値(デジタル署名), コードサイニング証明書 この3つをまとめて、パッケージを作成

ハッシュ値とは

データから算出される数字のこと。SHA-1、SHA256(SHA-2)等のハッシュ関数を使って算出する

元のデータが少しでも異なれば異なるハッシュ値が算出されるため

ファイルが改ざんされていないかを確認するために使うことができる

例として、Mac では sample.txt ファイルのハッシュ値を以下コマンドで取得できる

$ openssl sha1 sample.txt
SHA1(sample.txt)= fbe5aefc2fcbf125965974a476523b56baf632e1

fbe5aefc2fcbf125965974a476523b56baf632e1 が実際のハッシュ値である

検証(ユーザー側の処理)

  1. 証明書の有効性の確認と公開鍵の取得
  2. コード 暗号化されたハッシュ値(デジタル署名) に分離
  3. 暗号化されたハッシュ値(デジタル署名) を公開鍵で復号し証明書に含まれているハッシュ値を取得
  4. ダウンロードしたコードのハッシュ値を生成
  5. 二つのハッシュ値が一致 していればコードは改竄がなく、真正であることが証明される

Electron で autoUpdate をする方法

1. Githubリポジトリが Public の場合

 update.electronjs.org を使う

 ビルドコードは、コード証明されている必要があり、以下のような更新サーバーを別途用意する必要がある

  • Hazel
  • Nuts
  • electron-release-server
  • Nucleus

2. Githubリポジトリが Private の場合

 electron-builder の module electron-updater を使う

 更新サーバーを必要とせず、S3、GitHub、またはその他の静的ファイルホストからの更新が可能

👉 今回は 2. Githubリポジトリが Private の場合 なので electron-updater を使うことにします

autoUpdate するにあたり Electron で証明証が必要かどうか

Mac: 必要

Apple Developer Program に登録して証明書を発行する必要がある

Windows: 不要

Windowsストア経由にしない場合は、不要

Mac Apple Store (=MAS) 用に Electron の証明証を取得してみる

証明証は2種類ある

  1. Development 証明証 = 開発用にビルドするときに使う

  2. Production 証明証 = 本番で、Apple Store 公開するときに使う

今回は Development 証明証を取得してみます

必要な証明証は以下の2つ

  • Certificates (サーティフィケイツ)

  開発者登録用の証明書

  Certificates をキーチェーンアクセスに登録したPCでないとビルド出来ないようになっている、詳しくは後述します

  拡張子は .cer

  • Provisioning Profile (プロビジョニング プロファイル)

  Certificates Devices App ID を合わせて作られたもの

  ソフトウェアの開発者・販売者を、提供元のアップルに証明してもらうためのもの

  拡張子は .mobileprovision

1. Certificates を取得する

Certificates を取得するために

CertificateSigningRequest.certSigningRequest ファイルが必要になる

キーチェーンアクセス → 証明書アシスタント → 認証局に証明書を要求

ローカルに CertificateSigningRequest.certSigningRequest ファイルが保存される

次に、このファイルを使って Certificates を取得する

まず、Apple Developer Program に登録します( $100 / Year )

登録後以下のURLからサインインします

Certificates, IDs & Profiles → 左上プルダウンは macOSCertificates 項目の Development → 右上 + マーク

Mac Development を選択し、進めていく

ここで、先ほど作成した CertificateSigningRequest.certSigningRequest ファイルをアップロードする

最後に生成された Certificates をダウンロードする

これを実行すると、キーチェーンに証明証が追加され、完了

Electron Builder でビルド時に表示されるコンソールがこのように変わればOK

Certificates インストール前

Certificates インストール後

このように、キーチェーンに登録されている Certificates を Electron Builder がビルド時に自動的に見にいくようになっている

2. Provisioning Profile を取得する

Provisioning Profile を取得するために、 App ID を新規登録する必要があります

App ID とは、アプリケーションを識別するために使われ、プロファイルを作成するのに必要。

そのApp ID を新規登録する際に、Bundle ID(バンドルID) を決める必要がある

Bundle IDとはアプリケーションを識別するために使われ、ユニークである必要がある(既に Apple Store でリリースされているアプリケーションと被ってはいけない)

Bundle IDの文字列は、英数字(A-Z、a-z、0-9)、ハイフン(-)、ピリオド(.)のみで構成され、

組織のドメインがumamichi.comで、Helloという名前のアプリケーションを作成する場合、開発用の Bundle ID は以下にようになる

com.umamichi.Hello.dev

ここで決めたBundle IDは、後に Electron Builder 用に必要になるのでメモしておく

App IDApple Developer Program の画面から新規登録できる

app ID登録の詳細手順はこちらのApple公式サイト参照

App ID が登録できたら、いよいよ Provisioning Profile を新規作成する

App ID を選択する画面が出てくるので、先ほど新規登録した App ID を選択して進める

これで、App ID に紐づいた Provisioning Profile が作成される

ダウンロードしたファイルを実行することで、プロファイルにProvisioning Profileが追加される

さらに、package.jsonappId というキー名で Bundle ID を追加しておく必要がある

"build": {
  "appId": "com.umamichi.Hello.dev"

これで完了

S3 を使い autoUpdate する

S3 へアップロードする

S3にビルド後の以下のファイルをアップロードする

package.json に S3 URL を追記する

package.json に以下のように追記する

"build": {
    ...
    "mac": {
      "publish": [
        {
          "provider": "generic",
          "url": "https://s3-ap-northeast-1.amazonaws.com/[S3 URL]/"
        }
      ]
    }
    ...

ここでハマりやすいのが、 latest-mac.yml があるディレクトリのURLを指定すること

https://s3-ap-northeast-1.amazonaws.com/[S3 URL]/latest-mac.yml

とすると、動かない。

Electron を起動しているJSファイルで autoUpdater を呼び出す

メインプロセス

import { ipcMain } from 'electron';
import { autoUpdater } from 'electron-updater';

const log = require('electron-log');

... // 省略

// オートアップデーターからログが出力されるようにする。ログレベルは、Info
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'info';

// 最新バージョンがあるか、チェック開始
autoUpdater.checkForUpdates();

// アップデート可能な場合、レンダラプロセスに 'update-available' を送る
autoUpdater.addListener('update-available', (event) => {
 mainWindow.webContents.send('update-available');
 log.info('update-available');
});

// アップデート不可能な場合、レンダラプロセスに 'update-not-available' を送る
autoUpdater.addListener('update-not-available', () => {
 mainWindow.webContents.send('update-not-available');
 log.info('update-not-available');
});

// 失敗した場合、レンダラプロセスに 'update-error' を送る
autoUpdater.addListener('error', (error) => {
 mainWindow.webContents.send('update-error');
 log.info(error);
});

// ダウンロード中
autoUpdater.on('download-progress', (progressObj) => {
 mainWindow.webContents.send('update-download-progress', Math.floor(progressObj.percent));
 log.info('update-download-progress', Math.floor(progressObj.percent) + '%');
});

// ダウンロード完了
autoUpdater.addListener('update-downloaded', (
 event,
 releaseNotes,
 releaseName,
 releaseDate,
 updateURL,
) => {
 this.mainWindow.webContents.send('update-downloaded');
 log.info('update-downloaded');

 console.log('auto update done! quit and install start ---!');
 log.info('auto update done! quit and install start ---!');

 // Install and Reboot
 autoUpdater.quitAndInstall();

 return true;
});

まず、以下メソッドでチェックを開始する

autoUpdater.checkForUpdates();

アップデートが可能な場合、不可能な場合、それぞれイベントが定義されているので

それぞれに応じて、任意の処理を実行することができる

download-progress では、ダウンロードのパーセンテージの取得が可能

IPC通信を用いてレンダラプロセスに値を送り、UIに反映することもできる

最後に、

autoUpdater.quitAndInstall(); でインストールと再起動がされる

まとめ

  • Mac で electron-builder を使って Electron をビルドするときは、electron-builder が Mac のキーチェーンアクセスの中の証明書をみにいくようになっている

  • Mac で Electron autoUpdater をする場合は、証明書が必要で、そのためには Apple Developer Program($100/Year)に入る必要がある

  • Windowsの場合は、Electron autoUpdater をするときに、証明書は必要ない

これから検証

  • Mac の App Store 経由でインストール&アップデートする方法

  • 今回試した内容だと、Certificates だけで良いのでは・・?( Provisioning Profile は App Store 経由にするときに、必要になる?)

参考

Electron アプリを Mac App Store に登録する手順
https://qiita.com/9m/items/9df6eb44fefb14cb7ceb

[iPhone] Provisioning Profile を作ってみる
https://i-app-tec.com/ios/provisioning-profile.html

15
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
umamichi
Frontend Engineer 🎠
team-lab
最新のテクノロジーを活用したシステムやデジタルコンテンツの開発を行うウルトラテクノロジスト集団

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
15
Help us understand the problem. What is going on with this article?