Sparkleは、配布する更新のアーカイブをEdDSA(Ed25519)の署名で検証する。アプリは、Info.plistに埋め込まれた公開鍵で署名を検証し、一致した更新だけをインストールする。署名に使う鍵のペアは、Sparkleに含まれるgenerate_keysで生成する。

$ generate_keys
A key has been generated and saved in your keychain. Add the `SUPublicEDKey` key to
the Info.plist of each app for which you intend to use Sparkle for distributing
updates. It should appear like this:

    <key>SUPublicEDKey</key>
    <string>[公開鍵]</string>

秘密鍵はログインキーチェーンに保存され、公開鍵が表示される。公開鍵を、Info.plistのSUPublicEDKeyに設定する。実行例はSparkle 2.10.0、macOS 27.0.1のもの。

generate_keysの場所は、Sparkleの導入の記事で紹介している。

鍵を生成する

generate_keysを引数なしで実行すると、鍵のペアを生成する。

$ [Sparkleのbin]/generate_keys

秘密鍵はログインキーチェーンに保存される。公開鍵は、標準出力に表示される。公開鍵は、44文字のBase64の文字列である。

キーチェーンに保存された秘密鍵は、汎用パスワードの項目で、サービス名がhttps://sparkle-project.org、アカウント名がed25519である。

$ security find-generic-password -s "https://sparkle-project.org"
...
    "acct"<blob>="ed25519"
    "svce"<blob>="https://sparkle-project.org"

キーチェーンへのアクセスの許可を求められた場合は、許可する。

既に鍵がある場合は、既存の鍵が使われる

ログインキーチェーンに、すでにed25519の鍵がある場合、generate_keysは新しい鍵を生成しない。既存の鍵を使い、その公開鍵を表示する。generate_keys --helpにも、既存の鍵は上書きされないと書かれている。

別のアプリで同じMacから署名している場合、新しいアプリにも同じ鍵が使われる。アプリごとに鍵を分けたいときは、--accountでアカウント名を指定する。

$ [Sparkleのbin]/generate_keys --account [アカウント名]

--accountを指定すると、キーチェーンの項目のアカウント名が、指定した名前になる。別のアカウント名で生成した鍵は、既存のed25519の鍵とは別に保存される。

アカウント名を指定して生成した鍵は、署名や検証のときにも、同じ--accountを指定する必要がある。generate_appcastとsign_updateの既定のアカウントはed25519である。

公開鍵を再表示する

公開鍵は、-pで、あとから再表示できる。

$ [Sparkleのbin]/generate_keys -p
[公開鍵]

--accountで生成した鍵の場合は、同じ--accountを指定する。

$ [Sparkleのbin]/generate_keys --account [アカウント名] -p
[公開鍵]

公開鍵をInfo.plistに設定する

公開鍵を、アプリのInfo.plistのSUPublicEDKeyに設定する。Sparkleの導入の記事で作成したInfo.plistに、plutilで追加できる。

$ plutil -insert SUPublicEDKey -string "[公開鍵]" Info.plist
$ plutil -p Info.plist
{
  "SUEnableAutomaticChecks" => true
  "SUFeedURL" => "https://github.com/[ユーザー名]/[リポジトリ名]/releases/latest/download/appcast.xml"
  "SUPublicEDKey" => "[公開鍵]"
}

テキストエディタで、次のキーを追加してもよい。

<key>SUPublicEDKey</key>
<string>[公開鍵]</string>

秘密鍵をバックアップする

秘密鍵を失うと、既存のユーザーのアプリに、更新を配信できなくなる。ユーザーのアプリは、Info.plistに埋め込まれた公開鍵で更新を検証するためである。秘密鍵は、キーチェーンの中だけに置かず、安全な場所にバックアップする。

秘密鍵は、-xで、ファイルに書き出せる。

$ [Sparkleのbin]/generate_keys -x sparkle_private.key

書き出されたファイルは、44文字のBase64の文字列である。ファイルの内容は、秘密鍵そのものである。パスワードマネージャーなど、安全な場所に保管し、リポジトリにはコミットしない。

秘密鍵を別のMacやCIで使う

書き出した秘密鍵は、-fで、別のMacのキーチェーンに取り込める。

$ [Sparkleのbin]/generate_keys -f sparkle_private.key
Importing signing key..

取り込んだ後に、-pで公開鍵を表示すると、元の鍵と同じ公開鍵が表示される。

$ [Sparkleのbin]/generate_keys -p
[公開鍵]

取り込み先に、すでに鍵がある場合の動作は確認していない。別のアカウント名に取り込む場合は、--accountを指定する。

CIで署名するときは、鍵をキーチェーンに取り込まず、generate_appcastの--ed-key-fileにファイルまたは標準入力で渡す方法もある。秘密鍵は、GitHubのSecretsなどに登録する。

$ gh secret set SPARKLE_PRIVATE_KEY < sparkle_private.key

不要になった鍵を削除する

検証用に生成した鍵など、不要になった鍵は、キーチェーンの項目を削除する。サービス名とアカウント名を指定して、securityで削除する。

$ security delete-generic-password -s "https://sparkle-project.org" -a [アカウント名]

アカウント名を間違えると、実際に使っている鍵を削除してしまう。ed25519の鍵は、バックアップがあることを確認してから削除する。