16

私はQt5でMacアプリを開発しているので、Xcodeの外です。「開発者の身元を確認できないため、開くことができません」という警告を発行するのではなく、GateKeeper がクライアントのコンピューターでアプリを実行できるようにしたいと考えています。

アプリのデジタル署名に成功しましたが、GateKeeper にはまだこの苦情が付きものです。私は Apple 開発者証明書 (私はチーム エージェントです) を持っていますが、キーチェーンはそれが有効であると言っています。また、2 つの Apple ルート証明書もインストールしました。

コマンド ライン ユーティリティを使用してcodesign、アプリ フォルダー内のすべてのバイナリにデジタル署名し、さらにアプリ フォルダー自体にもデジタル署名します。いずれの場合も、codesign の応答は有益であり、エラーは表示されません。codesign を使用すると、実際にすべてのバイナリが署名され、実行されていることを確認できます

$ codesign --verify --deep --verbose=2 MyApp.app

は、すべてのバイナリが検証済みであることを示しています。さらに、次のように報告します。

MyApp.app: ディスク上で有効
MyApp.app: その指定要件を満たす

ランニング:

$ codesign -v --verbose=4 --display MyApp.app   

与える

Executable=/Users/xxx/trunk/yyy/deploy/release/MyApp.app/Contents/MacOS/MyApp
Identifier=aaaa.MyApp
Format=Mach-O Thin (x86_64)
CodeDirectory のバンドル v=20200 size=12461 flags=0x0 (なし) hashes=616+3 location=embedded
Hash type=sha1 size=20
CDHash=d1c12c783dac0e8d9a2b749fb896b11558cec8b6
Signature size=8532
Authority=Developer ID Application: XXXXXX
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=29 jul. 2015 12;04:40
Info.plist エントリ = 8
TeamIdentifier = YYYYY
封印されたリソース バージョン = 2 ルール = 12 ファイル = 10
内部要件数 = 1 サイズ = 180

これは問題ないようです。

ランニング

$ spctl -a -t exec -vv MyApp.app

すべてのバイナリで結果として得られる

MyApp.app: 承認された
source=Developer ID
origin=Developer ID アプリケーション: XXXX

これもOKのようです

アプリまたはアプリ フォルダー内のバイナリに対して、XCode コマンド ライン ツールの check-signature を実行します。

$ ./check-signature /Users/xxx/trunk/yyy/release/MyApp.app

結果として与える

(c) 2014 Apple Inc. 無断複写・転載を禁じます。
はい

いずれの場合も、これは望ましい結果です。

しかし、GateKeeper はまだアプリを受け入れておらず、開発者を確認できないという事実について不満を述べています。

[2015 年 7 月 17 日金曜日に著者が追加]

私は問題を見つけたと思います。それが機能なのかOSXのバグなのかはわかりません。stackoverflow question 19551298に大いに助けられました。

ファイルがインターネットからダウンロードされるたびに、それに関連付けられた拡張ファイル属性 com.apple.quarantine が取得されます。このダウンロードしたファイルを Finder でダブルクリックすると、GateKeeper には次の 2 つの可能性があります。

  1. ファイルが署名されていない場合、「不明な開発者など」というメッセージが表示されます

  2. ファイルがデジタル署名されると、「開発者を確認できませんなど」というメッセージが表示されます

どちらの場合も、MessageBox には 1 つのボタン ([OK] ボタン) しかありません。このボタンをクリックしても、MessageBox が閉じる以外は何も起こりません。

拡張属性が削除された場合 (xattr -d)、アプリケーションは署名されているかどうかにかかわらず実行されます。

アプリの Finder でマウスを右クリックしてアプリケーションを起動し、[開く] メニュー アクションをクリックすると、動作が異なります。再び 2 つのメッセージ ボックスの 1 つが表示されますが、ユーザーがアプリを開くためのボタンが追加されています。ここでも、署名されている場合と署名されていない場合の唯一の違いは、「未確認」または「確認されていません」というメッセージです。私の顧客が違いを語れるとは思っていません。その結果、アプリに署名することは無益な練習になります。

Apple サポート ドキュメントに基づいて、ダウンロードしたアプリをダブルクリックしたときの GateKeeper の別のより良い動作を期待しました (ドキュメントが古くなっているか、読み間違えている可能性があります)。

  1. アプリが署名されている場合、GateKeeper は「インターネットなどからダウンロードしました」というメッセージ ボックスと、「続行しますか?」というボタンを表示する必要があります。

  2. アプリが 1 つの [OK] ボタンと「不明な開発者など」というテキストを含む MessageBox に署名されていない場合。

4

5 に答える 5

18

自分の質問に答えて申し訳ありませんが、元の質問を編集するとスパゲッティテキストになるため、他に方法がありません。

私はついに私の問題を解決しました。最初の功績: (i) 私の他のスタックオーバーフローの質問への回答は非常に役に立ちました。(ii) いわゆるテクニカル サポート インシデント (TSI) を提出することで、公式の Apple 開発者から非常に良い (有償の) アドバイスを得ました。

これらすべてに基づいて、Mac アプリを GateKeeper で正常に処理する方法の非常に簡潔なレシピをここで示すことができます。レシピを詳述した後、私の最初の間違いが何であったかを示します.

目標: Xcode の外部で Mac アプリを開発し、GateKeeper が「インターネットからダウンロードされました...」という警告を 3 つのボタンで発行するようにした後、そのうちの 1 つが「開く」です。

失敗: GateKeeper がテキスト「.. unidentified developer..」またはテキスト「.. unconfirmed developer ..」のいずれかで警告を発した場合 - どちらの場合も - OK ボタンが 1 つあるメッセージボックス。

アプリを GateKeeper に対応させるには、次の 3 つの手順が必要です。

  • 受け入れがたい外部依存関係のないアプリをスタンドアロンにします。許容される唯一の外部依存関係は、システム ライブラリです。他のすべての依存関係は、MyApp.app フォルダーにコピーされているはずです。GateKeeper は、システム以外の外部依存関係を持つアプリを拒否します
  • バイナリは、MyApp.app フォルダー内の不正な場所に配置しないでください。ライブラリは MyApp/Contents/Frameworks に入り、実行可能ファイルは MyApp/Contents/MacOS に入ります
  • MyApp 内のすべてのバイナリは、デジタル署名する必要があります。次に、MyApp.app フォルダーに署名する必要があります。この署名には、Apple "Developer ID Application ..." 証明書が必要です

私たちのレシピは自動です。すべての作業は 1 つのスクリプトで実行されます。Qt Creator の場合、コマンドを介してシステム シェルにアクセスする qmake スクリプトを使用します$$system。(Xcode) システム コマンドのいずれかを使用する場合codesignspctlまたは質問への回答で説明されているように、check-signature stderr を stdout にリダイレクトしたと想定します。そうしないと、これらのユーティリティを実行したときにシステムの応答をキャッチできなくなります。以下では、このリダイレクトを明示的に示しません。

ここに私たちのレシピがあります

A. アプリをスタンドアロンにする:

  1. 必要なすべてのバイナリを (スクリプトを使用して) MyApp.folder にコピーします。
  2. (スクリプトを使用して) 実行し install_name_tool -changeinstall_name_tool -id アプリ内のすべての依存関係が相対型@executable_path/../MacOS..または@executable_path/../Frameworks
  3. MyApp.app フォルダー内のすべてのバイナリに対して(スクリプトを使用して) 実行し、otool -L"@rpath..." やシステム パスではない絶対ファイル パスなどの不正な依存関係にフラグを立てます。otool -Lすべての依存関係を見つけることが保証されているわけではないことに注意してください。プラグインは、多くの場合、otool. そのため、次のチェックが必要です。
  4. 「MyApp.app/Contents/MacOS」の場所でターミナルを起動します。実行しますexport DYLD_PRINT_LIBRARIES=1。次に、同じターミナル ウィンドウ内で実行します./MyApp。端末は、100 を超えるロード済みライブラリでいっぱいになります。禁止されているライブラリ (あなたのコンピュータには存在するが、顧客のコンピュータには存在しないライブラリ) について、このリストをもう一度確認してください。
  5. プリンの証は食べ方にあります。MacInCloud 仮想マシンを使用して、アプリがそこで実行されるかどうかを確認します。別の解決策として、開発者ではない親戚の Mac を使用することもできます。または、自分の Mac で新しいユーザー (「テスト」) を作成し、アプリをそのダウンロード (またはデスクトップ フォルダーなど) にコピーすることもできます。後者の場合、一時的に IDE のルート フォルダの名前を変更する必要があります。そうしないと、ユーザー「test」がそこに不足しているバイナリを見つけてしまいます。

B アプリへの署名

  1. 署名: スクリプトを使用codesign --force --verify --verbose --sign \"Developer ID Application: ....\" \"/path/to/binary\" して、アプリ内のすべてのバイナリに対して実行し、次にアプリ フォルダー自体に対して実行します。いずれの場合も、システムの応答がキャッチされます。いずれの場合も、文字列「signed Mach-O thin」が含まれている必要があります。
  2. 検証:codesign --verify --verbose \"/path/to/binary\"アプリ内の各バイナリとアプリ自体で (スクリプトを使用して) コマンドを実行し、システムの応答をキャッチします。いずれの場合も、「ディスク上で有効」および「指定された要件を満たす」という文字列が含まれている必要があります。
  3. GateKeeper チェック:spctl -a -t exec -vv /path/to/binary\" 各バイナリとアプリ フォルダー自体に対して (スクリプトを使用して) 実行します。システム応答がキャッチされます。すべての場合に、文字列「accepted source」を含める必要があります。
  4. check-signature:check-signature \"/path/to/banary\" 各バイナリとアプリ フォルダー自体に対して (スクリプトを使用して) 実行します。システム応答がキャッチされます。いずれの場合も、文字列「YES」が含まれている必要があります。

C 外部チェック

  1. アプリを 1 つの zip ファイルに圧縮します。クラウド サーバーの 1 つにアップロードする

  2. ゲートキーパーは、その一般的なゲートキーパーの役割に関する例外の長いリスト (通常は数百項目) を保持しています。GateKeeper をテストする場合は、アプリがそのリストに含まれていてはなりません。このリストを編集するよりもはるかに簡単な方法は、Mac に新しいユーザーを作成することです。そのユーザーでログインし、インターネット クラウド サーバーから zip ファイルをダウンロードします。Finder は自動的に圧縮を解除します。クリックして。GateKeeper がアプリケーションを開くことができると通知しているが、同時にインターネットからダウンロードされていることを警告している場合は、(白い) ビールを飲むときです。

ここに目的の GateKeeper 警告があります:ここに画像の説明を入力

私の間違い

各バイナリの結果を明示的に確認せずに、インストールと署名の多くを行いました。その後otool -L、いくつかのバイナリで使用しますが、すべてではありません。以前の Qt バージョンから Qt 5.5 にアップグレードすると、バイナリlibqminimal.dylibが追加の依存関係を獲得したという事実を見逃していましたQtDBus。私は気づいていませんでしたが、GateKeeper は気づきました。

Qt 開発者はmacdeployqt、Qt アプリケーションを Mac に展開するためだけに使用しない理由を疑問に思うかもしれません。そもそも、文書化されていないブラックボックス ユーティリティを使用しないのは好ましくありません。インターネット フォーラムでは、かなりの数の人々が の問題を報告していmacdeployqtます。さらに、otool-L異なる Qt バージョンを比較すると、Qt ライブラリのインストール場所が異なる場合があります (によって報告されています)。新しい Qt バージョンがあると、スクリプトはすぐに禁止された依存関係について叫び始めます。このようにして、この新しいバージョンで何が変更されたかについての情報を取得します。

于 2015-08-15T14:01:51.657 に答える