Windows 10 では、いくつかの種類のプログラムは、コード署名 (code signing) しなければ動作しない。
uiAccess='true'
とする場合, コード署名しなければ, 実行が許可されない.
このページでは, 組織で展開するようなプライベートなアプリケーションを想定して, コード署名の方法を解説する.
コード署名とは, プログラムのバイナリに, デジタル署名 (Digital signature) を付けることです。「署名」が signature で,「署名すること」が signing.
https://commons.wikimedia.org/wiki/File:Digital_Signature_diagram.svg
実行ファイルが改竄されていないことを証明し、実行ファイルの作成者を保証することができます。注意! 実行ファイルが正しく動作することを保証するものではありません。
作成時は, 次のようにします (signing);
実行時は, 次のステップで検証 (verification) されます;
デジタル署名についてはこちら; 2.4 デジタル署名 - PKI関連技術に関するコンテンツ
実行ファイルのフォーマットは署名を埋め込むことができますが、画像ファイルなどにはできません。そこで, UWPアプリでは, 配備する各ファイルのハッシュ値を集めたファイル AppxBlockMap.xml
を作り, さらにこのファイルのハッシュ値に対して署名する, という方法を採っている.
https://blogs.msdn.microsoft.com/windowsappdev_ja/2012/12/12/appx/
なので, UWPアプリでは, 署名が付いているのは 作り方が知りたい人は、次のセクションまで読み跳ばしてください。
マニフェストを表示してみる。SysInternals の SigCheck コマンドを使う.
赤字の部分, このバイナリの署名を表示してみる. SigCheck の -i オプション;
最終的に, Microsoft Root Certificate Authority 2010 まで繋がっていることが分かる。
アプリの実体は こっちは, Microsoft Root Certificate Authority 2011 がルートCAになっている。
.exe
ファイルではなく, AppxSignature.p7x
というファイル.
実際の例
Accessibility アプリケーション
> & 'C:\Program Files\SysinternalsSuite\sigcheck.exe' -m C:\windows\system32\Magnify.exe
Sigcheck v2.60 - File version and signature viewer
Copyright (C) 2004-2017 Mark Russinovich
Sysinternals - www.sysinternals.com
c:\windows\system32\Magnify.exe:
Verified: Signed
Signing date: 18:04 2018/03/03
Publisher: Microsoft Windows
Company: Microsoft Corporation
Description: Microsoft Screen Magnifier
Product: Microsoftョ Windowsョ Operating System
Prod version: 10.0.16299.248
File version: 10.0.16299.248 (WinBuild.160101.0800)
MachineType: 64-bit
Manifest:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (c) Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
name="Microsoft.Windows.EndUser.Magnify"
processorArchitecture="amd64"
version="5.1.0.0"
type="win32"/>
<description>Magnifier</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="true"/>
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*" />
</dependentAssembly>
</dependency>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">per monitor</dpiAware>
</windowsSettings>
</application>
</assembly>
<requestedExecutionLevel level="asInvoker" uiAccess="true"/>
がある。これがあると、強い権限がある分、実行時のチェックが厳しい.
> & 'C:\Program Files\SysinternalsSuite\sigcheck.exe' -i C:\windows\system32\Magnify.exe
Sigcheck v2.60 - File version and signature viewer
Copyright (C) 2004-2017 Mark Russinovich
Sysinternals - www.sysinternals.com
c:\windows\system32\Magnify.exe:
Verified: Signed
Link date: 23:15 1993/12/23
Signing date: 18:04 2018/03/03
Catalog: C:\WINDOWS\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1051_for_KB4088776~31bf3856ad364e35~amd64~~10.0.1.3.cat
Signers:
Microsoft Windows
Cert Status: Valid
Valid Usage: NT5 Crypto, Code Signing
Cert Issuer: Microsoft Windows Production PCA 2011
Serial Number: 33 00 00 01 74 69 DE 10 8B 37 65 A8 D7 00 00 00 00 01 74
Thumbprint: 419E77AED546A1A6CF4DC23C1F977542FE289CF7
Algorithm: sha256RSA
Valid from: 5:23 2017/08/12
Valid to: 5:23 2018/08/12
Microsoft Windows Production PCA 2011
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2010
Serial Number: 61 07 76 56 00 00 00 00 00 08
Thumbprint: 580A6F4CC4E4B669B9EBDC1B2B3E087B80D0678D
Algorithm: sha256RSA
Valid from: 3:41 2011/10/20
Valid to: 3:51 2026/10/20
Microsoft Root Certificate Authority 2010
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2010
Serial Number: 28 CC 3A 25 BF BA 44 AC 44 9A 9B 58 6B 43 39 AA
Thumbprint: 3B1EFD3A66EA28B16697394703A72CA340A05BD5
Algorithm: sha256RSA
Valid from: 6:57 2010/06/24
Valid to: 7:04 2035/06/24
Counter Signers:
Microsoft Time-Stamp Service
Cert Status: Valid
Valid Usage: Timestamp Signing
Cert Issuer: Microsoft Time-Stamp PCA 2010
Serial Number: 33 00 00 00 A5 48 17 72 27 F9 70 BE 63 00 00 00 00 00 A5
Thumbprint: 9BC235DDFBB2262B1A143165502F1D539469826F
Algorithm: sha256RSA
Valid from: 2:56 2016/09/08
Valid to: 2:56 2018/09/08
Microsoft Time-Stamp PCA 2010
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2010
Serial Number: 61 09 81 2A 00 00 00 00 00 02
Thumbprint: 2AA752FE64C49ABE82913C463529CF10FF2F04EE
Algorithm: sha256RSA
Valid from: 6:36 2010/07/02
Valid to: 6:46 2025/07/02
Microsoft Root Certificate Authority 2010
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2010
Serial Number: 28 CC 3A 25 BF BA 44 AC 44 9A 9B 58 6B 43 39 AA
Thumbprint: 3B1EFD3A66EA28B16697394703A72CA340A05BD5
Algorithm: sha256RSA
Valid from: 6:57 2010/06/24
Valid to: 7:04 2035/06/24
Company: Microsoft Corporation
Description: Microsoft Screen Magnifier
Product: Microsoftョ Windowsョ Operating System
Prod version: 10.0.16299.248
File version: 10.0.16299.248 (WinBuild.160101.0800)
MachineType: 64-bit
UWPアプリ
C:\Program Files\WindowsApps
以下にある. 上記のとおり, プログラムのほうではなく (または加えて), AppxSignature.p7x
ファイルに対して署名されている。
> & 'C:\Program Files\SysinternalsSuite\sigcheck.exe' -i .\AppxSignature.p7x
Sigcheck v2.60 - File version and signature viewer
Copyright (C) 2004-2017 Mark Russinovich
Sysinternals - www.sysinternals.com
C:\Program Files\WindowsApps\MomendYazilim.DriverXP_1.0.0.5_x86__fvhpr3fm9t3ag\AppxSignature.p7x:
Verified: Signed
File date: 14:22 2016/05/07
Signing date: 0:30 2015/04/15
Catalog: C:\Program Files\WindowsApps\MomendYazilim.DriverXP_1.0.0.5_x86__fvhpr3fm9t3ag\AppxSignature.p7x
Signers:
8F53F2DB-2125-42EA-A116-5C366768CCFE
Cert Status: This certificate or one of the certificates in the certificate chain is not time valid.
Valid Usage: Windows Store, Code Signing
Cert Issuer: Microsoft Marketplace CA G 008
Serial Number: 33 00 04 5A E4 8F 99 05 7B 6C 0E 7D 86 00 00 00 04 5A E4
Thumbprint: F26A03C4BC28905AAFE2949CFAA1B38ACF121F00
Algorithm: sha256RSA
Valid from: 0:18 2015/04/15
Valid to: 0:18 2015/04/18
Microsoft Marketplace CA G 008
Cert Status: This certificate or one of the certificates in the certificate chain is not time valid.
Valid Usage: All
Cert Issuer: Microsoft MarketPlace PCA 2011
Serial Number: 61 0B 25 C2 00 00 00 00 00 2E
Thumbprint: 15332841E977A756198CF09AE00C480944EB31B0
Algorithm: sha256RSA
Valid from: 5:31 2012/05/17
Valid to: 5:41 2015/05/17
Microsoft MarketPlace PCA 2011
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2011
Serial Number: 61 12 44 A2 00 00 00 00 00 02
Thumbprint: EB9204785126C26ADADCBBD44FE2B0C642A71078
Algorithm: sha256RSA
Valid from: 6:09 2011/03/29
Valid to: 6:19 2031/03/29
Microsoft Root Certificate Authority 2011
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2011
Serial Number: 3F 8B C8 B5 FC 9F B2 96 43 B5 69 D6 6C 42 E1 44
Thumbprint: 8F43288AD272F3103B6FB1428485EA3014C0BCFE
Algorithm: sha256RSA
Valid from: 7:05 2011/03/23
Valid to: 7:13 2036/03/23
Counter Signers:
Microsoft Time-Stamp Service
Cert Status: This certificate or one of the certificates in the certificate chain is not time valid.
Valid Usage: Timestamp Signing
Cert Issuer: Microsoft Time-Stamp PCA 2010
Serial Number: 33 00 00 00 55 6E 9D DA 5A A6 F3 1C 5B 00 00 00 00 00 55
Thumbprint: 51E945A7C9B57FB14A92177895425B4C2D4D66CE
Algorithm: sha256RSA
Valid from: 2:32 2015/03/21
Valid to: 2:32 2016/06/21
Microsoft Time-Stamp PCA 2010
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2010
Serial Number: 61 09 81 2A 00 00 00 00 00 02
Thumbprint: 2AA752FE64C49ABE82913C463529CF10FF2F04EE
Algorithm: sha256RSA
Valid from: 6:36 2010/07/02
Valid to: 6:46 2025/07/02
Microsoft Root Certificate Authority 2010
Cert Status: Valid
Valid Usage: All
Cert Issuer: Microsoft Root Certificate Authority 2010
Serial Number: 28 CC 3A 25 BF BA 44 AC 44 9A 9B 58 6B 43 39 AA
Thumbprint: 3B1EFD3A66EA28B16697394703A72CA340A05BD5
Algorithm: sha256RSA
Valid from: 6:57 2010/06/24
Valid to: 7:04 2035/06/24
Company: n/a
Description: n/a
Product: n/a
Prod version: n/a
File version: n/a
MachineType: n/a
バイナリに署名するには, 自分の秘密鍵と証明書の両方が必要です。証明書は、自分の公開鍵に対して認証局 (CA) が署名したものです。
CAに対して, 公開鍵に対する署名要求を出します。
以下は, 秘密鍵を同時に作る方法. すでに秘密鍵がある場合は, openssl req -new -key 秘密鍵ファイル名 -out CSRファイル名.
/usr/bin/CA.pl
ファイルは openssl-perl パッケージに含まれる。
$ /usr/bin/CA.pl -newreq ==== openssl req -new -keyout newkey.pem -out newreq.pem -days 365 Generating a 2048 bit RSA private key ......+++ .......................................+++ writing new private key to 'newkey.pem' Enter PEM pass phrase:秘密鍵のパスワード Verifying - Enter PEM pass phrase:確認 ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Fukuoka Locality Name (eg, city) [Default City]:Munakata Organization Name (eg, company) [Default Company Ltd]:Netsphere Laboratories Organizational Unit Name (eg, section) []:改行 Common Name (eg, your name or your server's hostname) []:Netsphere Laboratories Code Signing Email Address []:hisashi.horikawa@gmail.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:改行 An optional company name []:改行 ==> 0 ==== Request is in newreq.pem, private key is in newkey.pem
秘密鍵 (newkey.pem
ファイル) と 署名要求 (newreq.pem
) ができた。秘密鍵は秘密にしなければなりません。
/etc/pki/tls/openssl.cnf
をコピーして, 設定ファイルを作ります。
バイナリ作成者はCAではないので, CA:FALSE
.
目的は codeSigning
. コード署名の場合の keyUsage
は digitalSignature
があればよい。
[ v3_ca ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer # ここ basicConstraints = critical,CA:FALSE # Key usage: this is typical for a CA certificate. However since it will # prevent it being used as an test self-signed certificate it is best # left out by default. keyUsage = digitalSignature # これ extendedKeyUsage = critical,codeSigning
Storeアプリの AppxSignature.p7x
ファイルに付けられた証明書では, 目的は次の2つになっている:
後者は上の codeSigning
のこと。RFC 5280 May 2008; Obsoletes: 3280, 4325, 4630, で定義された, id-kp-codeSigning
.
前者は, <wincrypt.h>
でハードコードされている.
// Signer of Windows Store applications #define szOID_WINDOWS_STORE_SIGNER "1.3.6.1.4.1.311.76.3.1"
このような数字とピリオドの組み合わせで示された OID は, 例えば, 次のサイトで確認できる; OID Repository
CA.pl -signCA コマンドで, バイナリ作成者の公開鍵に署名して, 証明書を作る. カレントディレクトリに newreq.pem
ファイルが必要。
$ OPENSSL_CONFIG="-config code-signing.cnf" /usr/bin/CA.pl -signCA ==== openssl ca -config code-signing.cnf -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem Using configuration from code-signing.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 4661 (0x1235) Validity Not Before: Mar 4 04:57:34 2018 GMT Not After : Mar 4 04:57:34 2019 GMT Subject: countryName = JP stateOrProvinceName = Fukuoka localityName = Munakata organizationName = Netsphere Laboratories commonName = Netsphere Laboratories Code Signing emailAddress = hisashi.horikawa@gmail.com X509v3 extensions: X509v3 Subject Key Identifier: C5:37:D4:8C:A5:70:CE:5A:05:A2:4D:61:10:0E:5F:90:14:A1:C8:C4 X509v3 Authority Key Identifier: keyid:BE:CC:6A:D8:8D:D3:ED:4C:C1:52:77:5A:38:2F:41:9E:B8:8B:A1:BA X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature X509v3 Extended Key Usage: critical Code Signing Certificate is to be certified until Mar 4 04:57:34 2019 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated ==> 0 ==== Signed CA certificate is in newcert.pem
証明書が newcert.pem
として保存される。
再び、バイナリ作成者の手順。
Visual Studio でビルド時に自動的に署名させるには, PKCS #12ファイルを作ってやります。
PKCS #12は, 証明書と秘密鍵を一つのファイルに格納する形式。PKCS #12のファイルを「証明書」と呼ぶのは正しくない。混乱の元。
拡張子は .p12
または .pfx
(どちらでも可).
中間CAの証明書と、今回作ったバイナリ作成者の証明書と秘密鍵を一つにまとめます.
$ openssl pkcs12 -export -in code-signing.cert.pem \ -inkey code-signing.private.pem \ -certfile ../intermediate-ca/CA/cacert.pem -out code-signing.pfx Enter pass phrase for code-signing.private.pem:秘密鍵のパスワード Enter Export Password:改行 パスワードは空にしないと、ビルドに使えない Verifying - Enter Export Password:改行
パスワードを付けたままだと, あらかじめ証明書ストアに格納しないといけなかった、ような。メモし忘れた。
署名を行う端末でも、あらかじめroot証明書をストアへ格納しておくことが必要です (手順は後述)。
Visual Studio で署名する. 単に package.appxmanifest
のプロパティで, 先ほどの PKCS #12ファイルを指定すればOK.
SDK の SignTool sign コマンドで署名する. /aオプションで, 中間証明書も付けるのを忘れずに.
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x86\signtool" sign /f ..\..\certs\code-signing2.pfx /a x64\Debug\*.exe x64\Debug\*.dll
このセクションは、オレオレroot証明書を使った場合です。
実行時の検証に合格できるように, バイナリを配備 (deploy) するすべての端末で, root証明書を証明書ストアに格納します。
保存場所: ローカルコンピュータ (管理者権限が必要)
「証明書をすべて次のストアに配置」を選択. ストアを自分で選ぶ →「信頼されたルート証明機関」
この状態で、コード署名された実行ファイルの証明書が検証できればOKです。
失敗談: 最初, 中間CAとしてTLS用のを使ったら, バイナリ作成者の証明書の検証に失敗した。きちんと, ルートCAまでの経路それぞれについて, 目的フィールドもチェックされていた。エラい.