aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielle Roberts <daroberts@google.com>2016-07-27 21:14:38 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-07-27 21:14:38 +0000
commitf19bd1db9c4da8c66c6edc61bc6d4f4d2f5ccbb5 (patch)
treebb2ef00657b47a8f418026166e984131ba32d629
parentc7518a9e135374979d809baa289b7d5ab0a50647 (diff)
parenteb922462f7e05a3d967755e371109ed9ad782049 (diff)
downloadsource.android.com-f19bd1db9c4da8c66c6edc61bc6d4f4d2f5ccbb5.tar.gz
Docs: Add APK signing v2 to Security am: 2170f96097
am: eb922462f7 Change-Id: Ia0185bf9357709029a1a9ec99851faa73b459488
-rw-r--r--src/security/apksigning/index.jd138
-rw-r--r--src/security/apksigning/v2.jd368
-rw-r--r--src/security/images/apk-before-after-signing.pngbin0 -> 26026 bytes
-rw-r--r--src/security/images/apk-integrity-protection.pngbin0 -> 37382 bytes
-rw-r--r--src/security/images/apk-sections.pngbin0 -> 13194 bytes
-rw-r--r--src/security/images/apk-validation-process.pngbin0 -> 64414 bytes
-rw-r--r--src/security/overview/app-security.jd3
-rw-r--r--src/security/security_toc.cs10
8 files changed, 518 insertions, 1 deletions
diff --git a/src/security/apksigning/index.jd b/src/security/apksigning/index.jd
new file mode 100644
index 00000000..1145191d
--- /dev/null
+++ b/src/security/apksigning/index.jd
@@ -0,0 +1,138 @@
+page.title=Application Signing
+@jd:body
+
+<!--
+ Copyright 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol id="auto-toc">
+ </ol>
+ </div>
+</div>
+
+<p>
+Application signing allows developers to identify the author of the application
+and to update their application without creating complicated interfaces and
+permissions. Every application that is run on the Android platform must be <a
+href="https://developer.android.com/studio/publish/app-signing.html">signed by
+the developer</a>. Applications that attempt to install without being signed
+will be rejected by either Google Play or the package installer on the Android
+device.
+</p>
+<p>
+On Google Play, application signing bridges the trust Google has with the
+developer and the trust the developer has with their application. Developers
+know their application is provided, unmodified, to the Android device; and
+developers can be held accountable for behavior of their application.
+</p>
+<p>
+On Android, application signing is the first step to placing an application in
+its Application Sandbox. The signed application certificate defines which user
+ID is associated with which application; different applications run under
+different user IDs. Application signing ensures that one application cannot
+access any other application except through well-defined IPC.
+</p>
+<p>
+When an application (APK file) is installed onto an Android device, the Package
+Manager verifies that the APK has been properly signed with the certificate
+included in that APK. If the certificate (or, more accurately, the public key in
+the certificate) matches the key used to sign any other APK on the device, the
+new APK has the option to specify in the manifest that it will share a UID with
+the other similarly-signed APKs.
+</p>
+<p>
+Applications can be signed by a third-party (OEM, operator, alternative market)
+or self-signed. Android provides code signing using self-signed certificates
+that developers can generate without external assistance or permission.
+Applications do not have to be signed by a central authority. Android currently
+does not perform CA verification for application certificates.
+</p>
+<p>
+Applications are also able to declare security permissions at the Signature
+protection level, restricting access only to applications signed with the same
+key while maintaining distinct UIDs and Application Sandboxes. A closer
+relationship with a shared Application Sandbox is allowed via the <a
+href="https://developer.android.com/guide/topics/manifest/manifest-element.html#uid">shared
+UID feature</a> where two or more applications signed with same developer key
+can declare a shared UID in their manifest.
+</p>
+<h2>APK signing schemes</h2>
+<p>
+Android supports two application signing schemes, one based on JAR signing (v1
+scheme) and <a href="v2.html">APK Signature Scheme v2 (v2 scheme)</a>, which
+was introduced in Android Nougat (Android 7.0).
+</p>
+<p>
+For maximum compatibility, applications should be signed both with v1 and v2
+schemes. Android Nougat and newer devices install apps signed with v2 scheme
+more quickly than those signed only with v1 scheme. Older Android platforms
+ignore v2 signatures and thus need apps to contain v1 signatures.
+</p>
+<h3 id="v1">JAR signing (v1 scheme)</h3>
+<p>
+APK signing has been a part of Android from the beginning. It is based on <a
+href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File">
+signed JAR</a>. For details on using this scheme, see the Android Studio documentation on
+<a href="https://developer.android.com/studio/publish/app-signing.html">Signing
+your app</a>.
+</p>
+<p>
+v1 signatures do not protect some parts of the APK, such as ZIP metadata. The
+APK verifier needs to process lots of untrusted (not yet verified) data
+structures and then discard data not covered by the signatures. This offers a
+sizeable attack surface. Moreover, the APK verifier must uncompress all
+compressed entries, consuming more time and memory. To address these issues,
+Android 7.0 introduced APK Signature Scheme v2.
+</p>
+<h3 id="v2">APK Signature Scheme v2 (v2 scheme)</h3>
+<p>
+Android 7.0 introduces APK signature scheme v2 (v2 scheme). The contents of the
+APK are hashed and signed, then the resulting APK Signing Block is inserted
+into the APK. For details on applying the v2 scheme to an application, refer to
+<a href="https://developer.android.com/preview/api-overview.html#apk_signature_v2">APK
+Signature Scheme v2</a> in the Android N Developer Preview.
+</p>
+<p>
+During validation, v2 scheme treats the APK file as a blob and performs signature
+checking across the entire file. Any modification to the APK, including ZIP metadata
+modifications, invalidates the APK signature. This form of APK verification is
+substantially faster and enables detection of more classes of unauthorized
+modifications.
+</p>
+<p>
+The new format is backwards compatible, so APKs signed with the new signature
+format can be installed on older Android devices (which simply ignore the extra
+data added to the APK), as long as these APKs are also v1-signed.
+</p>
+<p>
+ <img src="../images/apk-validation-process.png" alt="APK signature verification process" id="figure1" />
+</p>
+<p class="img-caption"><strong>Figure 1.</strong> APK signature verification
+process (new steps in red)</p>
+
+<p>
+Whole-file hash of the APK is verified against the v2 signature stored in the
+APK Signing Block. The hash covers everything except the APK Signing Block,
+which contains the v2 signature. Any modification to the APK outside of the APK
+Signing Block invalidates the APK's v2 signature. APKs with stripped v2
+signature are rejected as well, because their v1 signature specifies that the
+APK was v2-signed, which makes Android Nougat and newer refuse to verify APKs
+using their v1 signatures.
+</p>
+
+<p>For details on the APK signature verification process, see the <a href="v2.html#verification">
+Verification section</a> of APK Signature Scheme v2.</p>
diff --git a/src/security/apksigning/v2.jd b/src/security/apksigning/v2.jd
new file mode 100644
index 00000000..6a2e7a9d
--- /dev/null
+++ b/src/security/apksigning/v2.jd
@@ -0,0 +1,368 @@
+page.title=APK Signature Scheme v2
+@jd:body
+
+<!--
+ Copyright 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol id="auto-toc">
+ </ol>
+ </div>
+</div>
+
+<p>
+APK Signature Scheme v2 is a whole-file signature scheme that increases
+verification speed and <a
+href="#integrity-protected-contents">strengthens integrity guarantees</a> by
+detecting any changes to the protected parts of the APK.
+</p>
+
+<p>
+Signing using APK Signature Scheme v2 inserts an <a
+href="#apk-signing-block">APK Signing Block</a> into the APK file immediately
+before the ZIP Central Directory section. Inside the APK Signing Block, v2
+signatures and signer identity information are stored in an <a
+href="#apk-signature-scheme-v2-block">APK Signature Scheme v2 Block</a>.
+</p>
+
+<p>
+ <img src="../images/apk-before-after-signing.png" alt="APK before and after signing" id="figure1" />
+</p>
+<p class="img-caption"><strong>Figure 1.</strong> APK before and after signing</p>
+
+<p>
+APK Signature Scheme v2 was introduced in Android 7.0 (Nougat). To make
+a APK installable on Android 6.0 (Marshmallow) and older devices, the
+APK should be signed using <a href="index.html#v1">JAR signing</a> before being
+signed with the v2 scheme.
+</p>
+
+
+<h2 id="apk-signing-block">APK Signing Block</h2>
+<p>
+To maintain backward-compatibility with the current APK format, v2 and newer APK
+signatures are stored inside an APK Signing Block, a new container introduced to
+support APK Signature Scheme v2. In an APK file, the APK Signing Block is located
+immediately before the ZIP Central Directory, which is located at the end of the file.
+</p>
+
+<p>
+The block contains ID-value pairs wrapped in a way that makes it easier to
+locate the block in the APK. The v2 signature of the APK is stored as an ID-value
+pair with ID 0x7109871a.
+</p>
+
+<h3 id="apk-signing-block-format">Format</h3>
+<p>
+The format of the APK Signing Block is as follows (all numeric fields are
+little-endian):
+</p>
+
+<ul>
+ <li><code>size of block</code> in bytes (excluding this field) (uint64)</li>
+ <li>Sequence of uint64-length-prefixed ID-value pairs:
+ <ul>
+ <li><code>ID</code> (uint32)</li>
+ <li><code>value</code> (variable-length: length of the pair - 4 bytes)</li>
+ </ul>
+ </li>
+ <li><code>size of block</code> in bytes—same as the very first field (uint64)</li>
+ <li><code>magic</code> “APK Sig Block 42” (16 bytes)</li>
+</ul>
+
+<p>
+APK is parsed by first finding the start of the ZIP Central Directory (by
+finding the ZIP End of Central Directory record at the end of the file, then
+reading the start offset of the Central Directory from the record). The
+<code>magic</code> value provides a quick way to establish that what precedes
+Central Directory is likely the APK Signing Block. The <code>size of
+block</code> value then efficiently points to the start of the block in the
+file.
+</p>
+
+<p>
+ID-value pairs with unknown IDs should be ignored when interpreting the
+block.
+</p>
+
+
+<h2 id="apk-signature-scheme-v2-block">APK Signature Scheme v2 Block</h2>
+<p>
+APK is signed by one or more signers/identities, each represented by a signing
+key. This information is stored as an APK Signature Scheme v2 Block. For each
+signer, the following information is stored:
+</p>
+
+<ul>
+ <li>(signature algorithm, digest, signature) tuples. The digest is stored to
+decouple signature verification from integrity checking of the APK’s contents.</li>
+ <li>X.509 certificate chain representing the signer’s identity.</li>
+ <li>Additional attributes as key-value pairs.</li>
+</ul>
+
+<p>
+For each signer, the APK is verified using a supported signature from the
+provided list. Signatures with unknown signature algorithms are ignored. It is
+up to each implementation to choose which signature to use when multiple
+supported signatures are encountered. This enables the introduction of stronger
+signing methods in the future in a backward-compatible way. The suggested
+approach is to verify the strongest signature.
+</p>
+
+<h3 id="apk-signature-scheme-v2-block-format">Format</h3>
+<p>
+APK Signature Scheme v2 Block is stored inside the APK Signing Block under ID
+<code>0x7109871a</code>.
+</p>
+
+<p>
+The format of the APK Signature Scheme v2 Block is as follows (all numeric
+values are little-endian, all length-prefixed fields use uint32 for length):
+</p>
+<ul>
+ <li>length-prefixed sequence of length-prefixed <code>signer</code>:
+ <ul>
+ <li>length-prefixed <code>signed data</code>:
+ <ul>
+ <li>length-prefixed sequence of length-prefixed <code>digests</code>:
+ <ul>
+ <li><code>signature algorithm ID</code> (uint32)</li>
+ <li>(length-prefixed) <code>digest</code>—see
+ <a href="#integrity-protected-contents">Integrity-protected Contents</a></li>
+ </ul>
+ </li>
+ <li>length-prefixed sequence of X.509 <code>certificates</code>:
+ <ul>
+ <li>length-prefixed X.509 <code>certificate</code> (ASN.1 DER form)</li>
+ </ul>
+ </li>
+ <li>length-prefixed sequence of length-prefixed <code>additional attributes</code>:
+ <ul>
+ <li><code>ID</code> (uint32)</li>
+ <li><code>value</code> (variable-length: length of the additional
+ attribute - 4 bytes)</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>length-prefixed sequence of length-prefixed <code>signatures</code>:
+ <ul>
+ <li><code>signature algorithm ID</code> (uint32)</li>
+ <li>length-prefixed <code>signature</code> over <code>signed data</code></li>
+ </ul>
+ </li>
+ <li>length-prefixed <code>public key</code> (SubjectPublicKeyInfo, ASN.1 DER form)</li>
+ </ul>
+ </li>
+</ul>
+
+<h4 id="signature-algorithm-ids">Signature Algorithm IDs</h4>
+<ul>
+ <li>0x0101—RSASSA-PSS with SHA2-256 digest, SHA2-256 MGF1, 32 bytes of salt,
+ trailer: 0xbc</li>
+ <li>0x0102—RSASSA-PSS with SHA2-512 digest, SHA2-512 MGF1, 64 bytes of salt,
+ trailer: 0xbc</li>
+ <li>0x0103—RSASSA-PKCS1-v1_5 with SHA2-256 digest. This is for build systems
+ which require deterministic signatures.</li>
+ <li>0x0104—RSASSA-PKCS1-v1_5 with SHA2-512 digest. This is for build systems
+ which require deterministic signatures.</li>
+ <li>0x0201—ECDSA with SHA2-256 digest</li>
+ <li>0x0202—ECDSA with SHA2-512 digest</li>
+ <li>0x0301—DSA with SHA2-256 digest</li>
+</ul>
+
+<p>
+All of the above signature algorithms are supported by the Android platform.
+Signing tools may support a subset of the algorithms.
+</p>
+
+<p>
+<strong>Supported keys sizes and EC curves:</strong>
+</p>
+
+<ul>
+ <li>RSA: 1024, 2048, 4096, 8192, 16384</li>
+ <li>EC: NIST P-256, P-384, P-521</li>
+ <li>DSA: 1024, 2048, 3072</li>
+</ul>
+
+<h2 id="integrity-protected-contents">Integrity-protected contents</h2>
+
+<p>
+For the purposes of protecting APK contents, an APK consists of four sections:
+</p>
+
+<ol>
+ <li>Contents of ZIP entries (from offset 0 until the start of APK Signing Block)</li>
+ <li>APK Signing Block</li>
+ <li>ZIP Central Directory</li>
+ <li>ZIP End of Central Directory</li>
+</ol>
+
+<p>
+ <img src="../images/apk-sections.png" alt="APK sections after signing" id="figure2" />
+</p>
+<p class="img-caption"><strong>Figure 2.</strong> APK sections after signing</p>
+
+<p>
+APK Signature Scheme v2 protects the integrity of sections 1, 3, 4, and the
+<code>signed data</code> blocks of the APK Signature Scheme v2 Block contained
+inside section 2.
+</p>
+
+<p>
+The integrity of sections 1, 3, and 4 is protected by one or more digests of
+their contents stored in <code>signed data</code> blocks which are, in
+turn, protected by one or more signatures.
+</p>
+
+<p>
+The digest over sections 1, 3, and 4 is computed as follows, similar to a
+two-level <a href="https://en.wikipedia.org/wiki/Merkle_tree">Merkle tree</a>.
+Each section is split into consecutive 1 MB (2<sup>20</sup> bytes) chunks. The last chunk
+in each section may be shorter. The digest of each chunk is computed over the
+concatenation of byte <code>0xa5</code>, the chunk’s length in bytes
+(little-endian uint32), and the chunk’s contents. The top-level digest is
+computed over the concatenation of byte <code>0x5a</code>, the number of chunks
+(little-endian uint32), and the concatenation of digests of the chunks in the
+order the chunks appear in the APK. The digest is computed in chunked fashion to
+enable to speed up the computation by parallelizing it.
+</p>
+
+<p>
+ <img src="../images/apk-integrity-protection.png" alt="APK digest" id="figure3" />
+</p>
+<p class="img-caption"><strong>Figure 3.</strong> APK digest</p>
+
+<p>
+Protection of section 4 (ZIP End of Central Directory) is complicated by the
+section containing the offset of ZIP Central Directory. The offset changes when
+the size of the APK Signing Block changes, for instance, when a new signature is
+added. Thus, when computing digest over the ZIP End of Central Directory, the
+field containing the offset of ZIP Central Directory must be treated as
+containing the offset of the APK Signing Block.
+</p>
+
+<h2 id="rollback-protections">Rollback Protections</h2>
+<p>
+An attacker could attempt to have a v2-signed APK verified as a v1-signed APK on
+Android platforms that support verifying v2-signed APK. To mitigate this attack,
+v2-signed APKs that are also v1-signed must contain an X-Android-APK-Signed
+attribute in the main section of their META-INF/*.SF files. The value of the
+attribute is a comma-separated set of APK signature scheme IDs (the ID of this
+scheme is 2). When verifying the v1 signature, APK verifier is required to
+reject APKs which do not have a signature for the APK signature scheme the
+verifier prefers from this set (e.g., v2 scheme). This protection relies on the
+fact that contents META-INF/*.SF files are protected by v1 signatures. See the
+section on
+<a href="#v1-verification">JAR signed APK verification</a>.
+</p>
+
+<p>
+An attacker could attempt to strip stronger signatures from the APK Signature
+Scheme v2 Block. To mitigate this attack, the list of signature algorithm IDs
+with which the APK was being signed is stored in the <code>signed data</code>
+block which is protected by each signature.
+</p>
+
+<h2 id="verification">Verification</h2>
+
+In Android 7.0, APKs can be verified according to the APK Signature Scheme v2
+(v2 scheme) or JAR signing (v1 scheme). Older platforms ignore v2 signatures
+and only verify v1 signatures.
+</p>
+
+<p>
+ <img src="../images/apk-validation-process.png" alt="APK signature verification process" id="figure4" />
+</p>
+<p class="img-caption"><strong>Figure 4.</strong> APK signature verification
+process (new steps in red)</p>
+
+<h3 id="v2-verification">APK Signature Scheme v2 verification</h3>
+<ol>
+ <li>Locate the APK Signing Block and verify that:
+ <ol>
+ <li>Two size fields of APK Signing Block contain the same value.</li>
+ <li>ZIP Central Directory is immediately followed by ZIP End of Central
+ Directory record.</li>
+ <li>ZIP End of Central Directory is not followed by more data.</li>
+ </ol>
+ </li>
+ <li>Locate the first APK Signature Scheme v2 Block inside the APK Signing Block.
+ If the v2 Block if present, proceed to step 3. Otherwise, fall back to
+ verifying the APK
+ <a href="#v1-verification">using v1 scheme</a>.</li>
+ <li>For each <code>signer</code> in the APK Signature Scheme v2 Block:
+ <ol>
+ <li>Choose the strongest supported <code>signature algorithm ID</code> from
+ <code>signatures</code>. The strength ordering is up to each
+ implementation/platform version.</li>
+ <li>Verify the corresponding <code>signature</code> from
+ <code>signatures</code> against <code>signed data</code> using <code>public
+ key</code>. (It is now safe to parse <code>signed data</code>.)</li>
+ <li>Verify that the ordered list of signature algorithm IDs in
+ <code>digests</code> and <code>signatures</code> is identical. (This is to
+ prevent signature stripping/addition.)</li>
+ <li><a href="#integrity-protected-contents">Compute the digest of APK
+ contents</a> using the same digest algorithm as the digest algorithm used by the
+ signature algorithm.</li>
+ <li>Verify that the computed digest is identical to the corresponding
+ <code>digest</code> from <code>digests</code>.</li>
+ <li>Verify that SubjectPublicKeyInfo of the first <code>certificate</code> of
+ <code>certificates</code> is identical to <code>public key</code>.</li>
+ </ol>
+ </li>
+ <li>Verification succeeds if at least one <code>signer</code> was found and
+ step 3 succeeded for each found <code>signer</code>.</li>
+</ol>
+
+<p class="note"><strong>Note</strong>: APK must not be verified using
+the v1 scheme if a failure occurs in step 3 or 4.
+</p>
+
+<h3 id="v1-verification">JAR-signed APK verification (v1 scheme)</h3>
+<p>
+The JAR-signed APK is a
+<a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File">standard
+signed JAR</a>, which must contain exactly the entries listed in
+META-INF/MANIFEST.MF and where all entries must be signed by the same set of
+signers. Its integrity is verified as follows:
+</p>
+
+<ol>
+ <li>Each signer is represented by a META-INF/&lt;signer&gt;.SF and
+ META-INF/&lt;signer&gt;.(RSA|DSA|EC) JAR entry.</li>
+ <li>&lt;signer&gt;.(RSA|DSA|EC) is a
+ <a href="https://tools.ietf.org/html/rfc5652">PKCS #7 CMS ContentInfo
+ with SignedData structure</a> whose signature is verified over the
+ &lt;signer&gt;.SF file.</li>
+ <li>&lt;signer&gt;.SF file contains a whole-file digest of the META-INF/MANIFEST.MF
+ and digests of each section of META-INF/MANIFEST.MF. The whole-file digest of
+ the MANIFEST.MF is verified. If that fails, the digest of each MANIFEST.MF
+ section is verified instead.</li>
+ <li>META-INF/MANIFEST.MF contains, for each integrity-protected JAR entry, a
+ correspondingly named section containing the digest of the entry’s uncompressed
+ contents. All these digests are verified.</li>
+ <li>APK verification fails if the APK contains JAR entries which are not listed
+ in the MANIFEST.MF and are not part of JAR signature.</li>
+</ol>
+
+<p>
+The protection chain is thus &lt;signer&gt;.(RSA|DSA|EC) -> &lt;signer&gt;.SF -> MANIFEST.MF
+-> contents of each integrity-protected JAR entry.
+</p>
+
diff --git a/src/security/images/apk-before-after-signing.png b/src/security/images/apk-before-after-signing.png
new file mode 100644
index 00000000..2202f628
--- /dev/null
+++ b/src/security/images/apk-before-after-signing.png
Binary files differ
diff --git a/src/security/images/apk-integrity-protection.png b/src/security/images/apk-integrity-protection.png
new file mode 100644
index 00000000..1b6e3170
--- /dev/null
+++ b/src/security/images/apk-integrity-protection.png
Binary files differ
diff --git a/src/security/images/apk-sections.png b/src/security/images/apk-sections.png
new file mode 100644
index 00000000..27b8af59
--- /dev/null
+++ b/src/security/images/apk-sections.png
Binary files differ
diff --git a/src/security/images/apk-validation-process.png b/src/security/images/apk-validation-process.png
new file mode 100644
index 00000000..c0b2b847
--- /dev/null
+++ b/src/security/images/apk-validation-process.png
Binary files differ
diff --git a/src/security/overview/app-security.jd b/src/security/overview/app-security.jd
index 8b011fac..053a5fe6 100644
--- a/src/security/overview/app-security.jd
+++ b/src/security/overview/app-security.jd
@@ -307,7 +307,8 @@ href="https://developer.android.com/preview/features/security-config.html">Netwo
Security Configuration</a> for more details.
</p>
<h2 id="application-signing">Application Signing</h2>
-<p>Code signing allows developers to identify the author of the application and to
+<p><a href="{@docRoot}security/apksigning/index.html">Code signing</a>
+ allows developers to identify the author of the application and to
update their application without creating complicated interfaces and
permissions. Every application that is run on the Android platform must be
signed by the developer. Applications that attempt to install without being
diff --git a/src/security/security_toc.cs b/src/security/security_toc.cs
index aa8f0da8..798e7e42 100644
--- a/src/security/security_toc.cs
+++ b/src/security/security_toc.cs
@@ -61,6 +61,16 @@
</li>
<li class="nav-section">
<div class="nav-section-header">
+ <a href="<?cs var:toroot ?>security/apksigning/index.html">
+ <span class="en">Application Signing</span>
+ </a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>security/apksigning/v2.html">APK Signature Scheme v2</a></li>
+ </ul>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header">
<a href="<?cs var:toroot ?>security/authentication/index.html">
<span class="en">Authentication</span>
</a>