Introduction

忘備録。

通常、Visual Studio を使ってコードサイニング証明書による署名を行った場合、タイムスタンプによる署名を忘れてしまい、コードサイニング証明書の有効期限が切れると、署名されたパッケージのインストールができなくなってしまう。

Windows 10 アプリ パッケージへの署名

下記は有効期限がきれたパッケージのインストールを試みた場合のエラーである。

1
2
3
4
$ .\Install.ps1
見つかったバンドル: D:\Demo_1.0.0.0_Debug_Test\Demo_1.0.0.0_x86_x64_arm_Debug.msixbundle
証明書が見つかりました: D:\Demo_1.0.0.0_Debug_Test\Demo_1.0.0.0_x86_x64_arm_Debug.cer
エラー: 開発者の証明書 "D:\Demo_1.0.0.0_Debug_Test\Demo_1.0.0.0_x86_x64_arm_Debug.cer" の有効期限が切れています。システム時計の日付と時刻が正しく設定されていないこ とが考えられます。システムの設定が正しい場合は、有効な証明書でパッケージまたはバンドルを再作成するようアプリ所有者に連絡してください。

このような場合でも、ビルドしなおすことなく、再署名することができる。

How to do?

状況によって手順が異なる。

証明書はこんな感じで作られたものを使用していたとする。
10分後に期限が切れる証明書である。

1
2
3
4
5
6
7
8
9
10
11
12
13
New-SelfSignedCertificate -Type Custom `
-Subject "CN=Contoso Software, O=Contoso Corporation, C=US" `
-KeyUsage DigitalSignature `
-FriendlyName "TestSelfSignedCertificate" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") `
-NotAfter (Get-Date).AddMinutes(10)

PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint Subject
---------- -------
283373D6C94724DDF37A16A6F31421DEA1426A60 CN=Contoso Software, O=Contoso Corporation, C=US

Publisher が同一の場合

再署名対象のパッケージの Publisher と再署名に用いる証明書の Subject が同一の場合。
下記のようなケース

Package.appxmanifest

1
2
3
4
<Identity
Name="f5474d04-dc34-46ff-8ce2-2b1bee87a545"
Publisher="CN=Contoso Software, O=Contoso Corporation, C=US"
Version="1.0.0.0" />

証明書

SelfSignedCertificate

再署名のコマンド

新しい証明書を作成する。

1
2
3
4
5
6
7
8
9
10
11
12
13
New-SelfSignedCertificate -Type Custom `
-Subject "CN=Contoso Software, O=Contoso Corporation, C=US" `
-KeyUsage DigitalSignature `
-FriendlyName "TestSelfSignedCertificate" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") `
-NotAfter (Get-Date).AddYears(100)

PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint Subject
---------- -------
DD96DD85D29D386C201985E86C40742A0740F812 CN=Contoso Software, O=Contoso Corporation, C=US

SelfSignedCertificate

上記のダイアログから拇印を確認します。
その後、下記のコマンドを実行。
Demo_1.0.0.0_x86_x64_arm_Debug.cer は再署名するパッケージに含まれているものと同じ名前にすること。

1
2
3
4
5
Export-Certificate -Cert cert:\currentuser\my\DD96DD85D29D386C201985E86C40742A0740F812 `
-FilePath .\Demo_1.0.0.0_x86_x64_arm_Debug.cer
Export-PfxCertificate -Cert cert:\currentuser\my\DD96DD85D29D386C201985E86C40742A0740F812 `
-FilePath key.pfx `
-Password $(ConvertTo-SecureString -String "pwd" -Force -AsPlainText)

実行後、

  • Demo_1.0.0.0_x86_x64_arm_Debug.cer
  • key.pfx

が生成される。
Demo_1.0.0.0_x86_x64_arm_Debug.cer をパッケージに入っていたものと入れ替えます。

次に下記を実行。

1
2
3
4
5
6
7
8
> "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /fd sha256 ^
/a ^
/f key.pfx ^
/p pwd ^
/t http://timestamp.digicert.com ^
.\Demo_1.0.0.0_x86_x64_arm_Debug.msixbundle
Done Adding Additional Store
Successfully signed: .\Demo_1.0.0.0_x86_x64_arm_Debug.msixbundle

以上でパッケージが再署名された。
/t はなくてもよいが、つけると下記のようにタイムスタンプ付になる。

Timestamp

再度インストールを試みる。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ .\Install.ps1
見つかったバンドル: D:\Demo_1.0.0.0_Debug_Test\Demo_1.0.0.0_x86_x64_arm_Debug.msixbundle
証明書が見つかりました: D:\Demo_1.0.0.0_Debug_Test\Demo_1.0.0.0_x86_x64_arm_Debug.cer このアプリをインストールする前に、以下を行う必要があります。 - 署名用証明書をインストールします 証明書は正常にインストールされました。
アプリをインストールしています...
依存関係パッケージが見つかりました:
D:\Demo_1.0.0.0_Debug_Test\Dependencies\x86\Microsoft.NET.CoreFramework.Debug.2.2.appx
D:\Demo_1.0.0.0_Debug_Test\Dependencies\x86\Microsoft.NET.CoreRuntime.2.2.appx
D:\Demo_1.0.0.0_Debug_Test\Dependencies\x86\Microsoft.VCLibs.x86.Debug.14.00.appx
D:\Demo_1.0.0.0_Debug_Test\Dependencies\x64\Microsoft.NET.CoreFramework.Debug.2.2.appx
D:\Demo_1.0.0.0_Debug_Test\Dependencies\x64\Microsoft.NET.CoreRuntime.2.2.appx
D:\Demo_1.0.0.0_Debug_Test\Dependencies\x64\Microsoft.VCLibs.x64.Debug.14.00.appx

成功: アプリは正常にインストールされました。

成功する。

Publisher が異なる

このケースは少し面倒。
また、*.msix の場合は上手く言ったが、*.msixbundle には成功しなかったので、下記の手順は一部違う点がある事に注意。

新しく下記のコマンドで証明書を作成。
Subjectが少し変わっている。

1
2
3
4
5
6
7
8
9
10
11
12
New-SelfSignedCertificate -Type Custom `
-Subject "CN=Contoso Software, O=Contoso Corporation, C=JP" `
-KeyUsage DigitalSignature `
-FriendlyName "TestSelfSignedCertificate" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") `
-NotAfter (Get-Date).AddYears(100)
PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint Subject
---------- -------
DF3FBD2431C2418391BA8AD0F999B43C479E64ED CN=Contoso Software, O=Contoso Corporation, C=JP

Exportを実行。

1
2
3
4
5
Export-Certificate -Cert cert:\currentuser\my\DF3FBD2431C2418391BA8AD0F999B43C479E64ED `
-FilePath .\Demo_1.0.0.0_x86_x64_arm_Debug.cer
Export-PfxCertificate -Cert cert:\currentuser\my\DF3FBD2431C2418391BA8AD0F999B43C479E64ED `
-FilePath key.pfx `
-Password $(ConvertTo-SecureString -String "pwd" -Force -AsPlainText)

次に下記を実行すると…

1
2
3
4
5
6
7
8
> "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /fd sha256 ^
/a ^
/f key.pfx ^
/p pwd ^
.\Demo_1.0.0.0_x64_Debug.msix
Done Adding Additional Store
SignTool Error: An unexpected internal error has occurred.
Error information: "Error: SignerSign() failed." (-2147024885/0x8007000b)

エラーになってしまう。

エラーの原因について

エラーコードがわかりづらく、署名エラーのトラブルはイベントビューアから実行する。
アプリ パッケージ署名エラーのトラブルシューティング

イベントビューアの イベント ビューアー (ローカル) > アプリケーションとサービス ログ > Microsoft > Windows > AppxPackagingOM > Microsoft-Windows-AppxPackaging/Operational を見ると、

Error

のように、発行元が変わったことで署名できなかったことが通知されている。

署名に使う証明書は変更できないので、再署名対象のパッケージに手を加える。

*.msix の書き換え

手順としては

  1. *.msix をzipとしてフォルダに展開
  2. AppxManifest.xml の中の Publisher を新しい証明書の Subject と同じ内容に書き換える
  3. 書き換えた後のフォルダをパッケージ

になる。

AppxManifest.xml の修正

AppxManifest.xml

1
2
-  <Identity Name="f5474d04-dc34-46ff-8ce2-2b1bee87a545" Publisher="CN=Contoso Software, O=Contoso Corporation, C=US" Version="1.0.0.0" ProcessorArchitecture="arm"/>
+ <Identity Name="f5474d04-dc34-46ff-8ce2-2b1bee87a545" Publisher="CN=Contoso Software, O=Contoso Corporation, C=JP" Version="1.0.0.0" ProcessorArchitecture="arm"/>

になる感じ。

新しい *.msix の作成

公式に MakeAppx というコマンドが用意されているのでそれを使う。
下記のような感じで、展開して編集した msix のフォルダを再度 msix にパッケージする。

1
2
$ "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\makeappx.exe" pack /d Demo_1.0.0.0_x64_Debug ^
/p Demo_1.0.0.0_x64_Debug.msix

あとは同様の手順で再署名するだけである。