We covered a somewhat boring, thus nosotros volition explore something unlike instead: code signing. This especial aspect of Android has remained virtually unchanged since the start populace release, as well as is thus key to the platform, that is pretty much taken for granted. While neither Java code signing, nor its Android implementation are specially new, some of the finer details are non specially well-known, thus we'll essay to shed some to a greater extent than low-cal on those. The start ship service of the serial volition concentrate on the signature formats used piece the adjacent ane volition facial expression into how code signing fits into Android's security model.
Java code signing
As nosotros all know, Android applications are coded (mostly) inward Java, as well as Android application bundle files (APKs) are only weird-looking JARs, thus it pays to sympathise how JAR signing industrial plant first.
First off, a few words nigh code signing inward general. Why would anyone desire to sign code? For the commons reasons: integrity as well as authenticity. Basically, earlier executing whatever third-party programme yous desire to brand for sure that it hasn't been tampered amongst (integrity) as well as that it was truly created past times the entity that it claims to come upwardly from (authenticity). Those features are ordinarily implemented past times some digital signature scheme, which guarantees that only the entity owning the signing key tin create a valid code signature. The signature verification physical care for verifies both that the code has non been tampered amongst as well as that the signature was produced amongst the expected key. One work that code signing doesn't solve direct is whether the code signer (software publisher) tin endure trusted. The commons agency trust is handled is past times requiring the code signer to concur a digital certificate, which they attach to the signed code. Verifiers determine whether to trust the certificate either based on some trust model (e.g., PKI or spider web of trust), or on a case-by-case basis. Another work that code signing does non solve (or trial get to) is whether the signed code is security to run. As nosotros receive got seen, code that has been signed (or appears to be) past times a trusted 3rd political party is non necessarily security (e.g., Flame or new security feature introduced inward the finally Jelly Bean maintenance loose inward our finally ship service and, earlier yous know it, a somewhat boring, thus nosotros volition explore something unlike instead: code signing. This especial aspect of Android has remained virtually unchanged since the start populace release, as well as is thus key to the platform, that is pretty much taken for granted. While neither Java code signing, nor its Android implementation are specially new, some of the finer details are non specially well-known, thus we'll essay to shed some to a greater extent than low-cal on those. The start ship service of the serial volition concentrate on the signature formats used piece the adjacent ane volition facial expression into how code signing fits into Android's security model.
Once yous receive got the needed keys, yous tin sign an APK similar this:
Nothing novel thus far, except the somewhat exotic (but easily parsable past times JCE classes) key format. However, the
Java code signing
As nosotros all know, Android applications are coded (mostly) inward Java, as well as Android application bundle files (APKs) are only weird-looking JARs, thus it pays to sympathise how JAR signing industrial plant first.
First off, a few words nigh code signing inward general. Why would anyone desire to sign code? For the commons reasons: integrity as well as authenticity. Basically, earlier executing whatever third-party programme yous desire to brand for sure that it hasn't been tampered amongst (integrity) as well as that it was truly created past times the entity that it claims to come upwardly from (authenticity). Those features are ordinarily implemented past times some digital signature scheme, which guarantees that only the entity owning the signing key tin create a valid code signature. The signature verification physical care for verifies both that the code has non been tampered amongst as well as that the signature was produced amongst the expected key. One work that code signing doesn't solve direct is whether the code signer (software publisher) tin endure trusted. The commons agency trust is handled is past times requiring the code signer to concur a digital certificate, which they attach to the signed code. Verifiers determine whether to trust the certificate either based on some trust model (e.g., PKI or spider web of trust), or on a case-by-case basis. Another work that code signing does non solve (or trial get to) is whether the signed code is security to run. As nosotros receive got seen, code that has been signed (or appears to be) past times a trusted 3rd political party is non necessarily security (e.g., Flame or pwdump7).
Java's native code packaging format is the JAR file, which is essentially a ZIP file bundling together code (
Java code signing is implemented at the JAR file bird past times adding some other manifest file, called a signature file (
The digests inward the signature file tin easily endure verified past times using the next OpenSSL commands:
The start ane takes the SHA1 digest of the entire manifest file as well as encodes it to Base 64 to create the
If nosotros extract the contents of a JAR file, nosotros tin purpose the OpenSSL
The official tools for JAR signing as well as verification are the
The finally ascendancy verifies the signature block as well as signing certificate, ensuring that the signature file has non been tampered with. It thus verifies that each digest inward the signature file (
Once yous know the signature block file advert (by listing the archive contents, for example), yous tin also purpose OpenSSL inward combination amongst the
Java's native code packaging format is the JAR file, which is essentially a ZIP file bundling together code (
.class
files or classes.dex
inward Android), some metadata nigh the bundle (.MF
manifest files inward the META-INF/ directory) and, optionally, resources the code uses. The master copy manifest file (MANIFEST.MF
) has entries amongst the file advert as well as digest value of each file inward the archive. The start of the manifest file of a typical APK file is demo below (we'll purpose APKs instead of actual JARs for all examples). Manifest-Version: 1.0 Created-By: 1.0 (Android) Name: res/drawable-xhdpi/ic_launcher.png SHA1-Digest: K/0Rd/lt0qSlgDD/9DY7aCNlBvU= Name: res/menu/main.xml SHA1-Digest: kG8WDil9ur0f+F2AxgcSSKDhjn0= Name: ...
Java code signing is implemented at the JAR file bird past times adding some other manifest file, called a signature file (
.SF
) which contains the information to endure signed, as well as a digital signature over it (called a 'signature block file', .RSA,
.DSA
or .EC
). The signature file is really similar to the manifest, as well as contains the digest of the whole manifest file (SHA1-Digest-Manifest
), equally good equally digests for each of the private entries inward MANIFEST.MF
.Signature-Version: 1.0 SHA1-Digest-Manifest-Main-Attributes: ZKXxNW/3Rg7JA1r0+RlbJIP6IMA= Created-By: 1.6.0_45 (Sun Microsystems Inc.) SHA1-Digest-Manifest: zb0XjEhVBxE0z2ZC+B4OW25WBxo= Name: res/drawable-xhdpi/ic_launcher.png SHA1-Digest: jTeE2Y5L3uBdQ2g40PB2n72L3dE= Name: res/menu/main.xml SHA1-Digest: kSQDLtTE07cLhTH/cY54UjbbNBo= Name: ...
The digests inward the signature file tin easily endure verified past times using the next OpenSSL commands:
$ openssl sha1 -binary MANIFEST.MF |openssl base64 zb0XjEhVBxE0z2ZC+B4OW25WBxo= $ echo -en "Name: res/drawable-xhdpi/ic_launcher.png\r\nSHA1-Digest: \ K/0Rd/lt0qSlgDD/9DY7aCNlBvU=\r\n\r\n"|openssl sha1 -binary |openssl base64 jTeE2Y5L3uBdQ2g40PB2n72L3dE=
The start ane takes the SHA1 digest of the entire manifest file as well as encodes it to Base 64 to create the
SHA1-Digest-Manifest
value, as well as the mo ane simulates how the digest of a unmarried manifest entry is existence calculated. The actual digital signature is inward binary PKCS#7 (or to a greater extent than generally, CMS) format as well as includes the signature value as well as signing certificate. Signature block files produced using the RSA algorithm are saved amongst the extension .RSA
, those generated amongst DSA or EC keys amongst the .DSA
or .EC
extensions, respectively. Multiple signatures tin endure performed, resulting inward multiple .SF
as well as .RSA/DSA/EC
files inward the JAR file's META-INF/
directory. The CMS format is rather involved, allowing non only for signing, but for encryption equally well, both amongst unlike algorithms as well as parameters, as well as is extensible via custom signed or unsigned attributes. Influenza A virus subtype H5N1 thorough give-and-take is beyond the orbit of this post, but equally used for JAR signing it basically contains the digest algorithm, signing certificate as well as signature value. Optionally the signed information tin endure included inward the SignedData
CMS construction (attached signature), but JAR signatures don't include it (detached signature). Here's how an RSA signature block file looks similar when parsed into ASN.1 (certificate information trimmed):$ openssl asn1parse -i -inform DER -in CERT.RSA 0:d=0 hl=4 l= 888 cons: SEQUENCE 4:d=1 hl=2 l= nine prim: OBJECT :pkcs7-signedData 15:d=1 hl=4 l= 873 cons: cont [ 0 ] 19:d=2 hl=4 l= 869 cons: SEQUENCE 23:d=3 hl=2 l= 1 prim: INTEGER :01 26:d=3 hl=2 l= eleven cons: SET 28:d=4 hl=2 l= nine cons: SEQUENCE 30:d=5 hl=2 l= five prim: OBJECT :sha1 37:d=5 hl=2 l= 0 prim: NULL 39:d=3 hl=2 l= eleven cons: SEQUENCE 41:d=4 hl=2 l= nine prim: OBJECT :pkcs7-data 52:d=3 hl=4 l= 607 cons: cont [ 0 ] 56:d=4 hl=4 l= 603 cons: SEQUENCE 60:d=5 hl=4 l= 452 cons: SEQUENCE 64:d=6 hl=2 l= three cons: cont [ 0 ] 66:d=7 hl=2 l= 1 prim: INTEGER :02 69:d=6 hl=2 l= 1 prim: INTEGER :04 72:d=6 hl=2 l= xiii cons: SEQUENCE 74:d=7 hl=2 l= nine prim: OBJECT :sha1WithRSAEncryption 85:d=7 hl=2 l= 0 prim: NULL 87:d=6 hl=2 l= 56 cons: SEQUENCE 89:d=7 hl=2 l= eleven cons: SET 91:d=8 hl=2 l= nine cons: SEQUENCE 93:d=9 hl=2 l= three prim: OBJECT :countryName 98:d=9 hl=2 l= 2 prim: PRINTABLESTRING :JP ... 735:d=5 hl=2 l= nine cons: SEQUENCE 737:d=6 hl=2 l= five prim: OBJECT :sha1 744:d=6 hl=2 l= 0 prim: NULL 746:d=5 hl=2 l= xiii cons: SEQUENCE 748:d=6 hl=2 l= nine prim: OBJECT :rsaEncryption 759:d=6 hl=2 l= 0 prim: NULL 761:d=5 hl=3 l= 128 prim: OCTET STRING [HEX DUMP]:892744D30DCEDF74933007...
If nosotros extract the contents of a JAR file, nosotros tin purpose the OpenSSL
smime
(CMS is the footing of S/MIME) ascendancy to verify its signature past times specifying the signature file equally the content (signed data). It volition impress the signed information as well as the verification result:$ openssl smime -verify -in CERT.RSA -inform DER -content CERT.SF signing-cert.pem Signature-Version: 1.0 SHA1-Digest-Manifest-Main-Attributes: ZKXxNW/3Rg7JA1r0+RlbJIP6IMA= Created-By: 1.6.0_43 (Sun Microsystems Inc.) SHA1-Digest-Manifest: zb0XjEhVBxE0z2ZC+B4OW25WBxo= Name: res/drawable-xhdpi/ic_launcher.png SHA1-Digest: jTeE2Y5L3uBdQ2g40PB2n72L3dE= ... Verification successful
The official tools for JAR signing as well as verification are the
jarsigner
as well as keytool
commands from the JDK. Since Java 5.0 jarsigner
also supports timestamping the signature past times a TSA, which could endure quite useful when yous take away to ascertain the fourth dimension of signing (e.g., earlier or later the signing certificate expired), but this characteristic is non widely used. Using the jarsigner
command, a JAR file is signed past times specifying a keystore file, the alias of the key to purpose for signing (used equally the base of operations advert for the signature block file) and, optionally, a signature algorithm. One affair to greenback is that since Java 7, the default algorithm has changed to SHA256withRSA
, thus yous take away to explicitly specify it if yous desire to purpose SHA1. Verification is performed inward a similar fashion, but the keystore file is used to search for trusted certificates, if specified. (again using an APK file instead of an actual JAR):$ jarsigner -keystore debug.keystore -sigalg SHA1withRSA test.apk androiddebugkey $ jarsigner -keystore debug.keystore -verify -verbose -certs test.apk .... smk 965 Monday April 08 23:55:34 JST 2013 res/drawable-xxhdpi/ic_launcher.png X.509, CN=Android Debug, O=Android, C=US (androiddebugkey) [certificate is valid from 6/18/11 7:31 PM to 6/10/41 7:31 PM] smk 458072 Tue April 09 01:16:18 JST 2013 classes.dex X.509, CN=Android Debug, O=Android, C=US (androiddebugkey) [certificate is valid from 6/18/11 7:31 PM to 6/10/41 7:31 PM] 903 Tue April 09 01:16:18 JST 2013 META-INF/MANIFEST.MF 956 Tue April 09 01:16:18 JST 2013 META-INF/CERT.SF 776 Tue April 09 01:16:18 JST 2013 META-INF/CERT.RSA s = signature was verified thousand = entry is listed inward manifest k = at to the lowest degree ane certificate was flora inward keystore i = at to the lowest degree ane certificate was flora inward identity orbit jounce verified.
The finally ascendancy verifies the signature block as well as signing certificate, ensuring that the signature file has non been tampered with. It thus verifies that each digest inward the signature file (
CERT.SF
) matches its corresponding department inward the manifest file (MANIFEST.MF
). One affair to greenback is that the issue of entries inward the signature file does non necessarily receive got to represent those inward the manifest file. Files tin endure added to a signed JAR without invalidating its signature: equally long equally none of the original files receive got been changed, verification succeeds. Finally, jarsigner
reads each manifest entry as well as checks that the file digest matches the actual file contents. Optionally, it checks whether the signing certificate is nowadays inward the specified key shop (if any). As of Java seven at that spot is a novel -strict
selection that volition perform additional certificate validations. Validation errors are treated equally warnings as well as reflected inward the move out code of the jarsigner
command. As yous tin see, it prints certificate details for each entry, fifty-fifty though they are the same for all entries. Influenza A virus subtype H5N1 slightly meliorate agency to thought signer information when using Java seven is to specify the -verbose:summary
or -verbose:grouped
, or alternatively purpose the keytool
command: $ keytool -list -printcert -jarfile test.apk Signer #1: Signature: Owner: CN=Android Debug, O=Android, C=US Issuer: CN=Android Debug, O=Android, C=US Serial number: 4dfc7e9a Valid from: Sabbatum Jun xviii 19:31:54 JST 2011 until: Monday Jun 10 19:31:54 JST 2041 Certificate fingerprints: MD5: E8:93:6E:43:99:61:C8:37:E1:30:36:14:CF:71:C2:32 SHA1: 08:53:74:41:50:26:07:E7:8F:A5:5F:56:4B:11:62:52:06:54:83:BE Signature algorithm name: SHA1withRSA Version: three
Once yous know the signature block file advert (by listing the archive contents, for example), yous tin also purpose OpenSSL inward combination amongst the
zip
ascendancy to easily extract the signing certificate to a file:$ unzip -q -c test.apk META-INF/CERT.RSA|openssl pkcs7 -inform DER -print_certs -out cert.pem
Android code signing
As evident from the examples above, Android code signing is based on Java JAR signing as well as yous tin purpose the regular JDK tools to sign or verify APKs. Besides those, at that spot is an Android specific tool inward the AOSPbuild/
directory, aptly named signapk
. It performs pretty much the same chore as jarsigner
inward signing mode, but at that spot are also a few notable differences. To start with, piece jarsigner
requires keys to endure stored inward a compatible key shop file, signapk
takes split upwardly signing key (in PKCS#8 format) as well as certificate (in DER format) files equally input. While it does appear to receive got some back upwardly for reading DSA keys, it tin only create signatures amongst the SHA1withRSA
mechanism. Raw private keys inward PKCS#8 are somewhat difficult to come upwardly by, but yous tin easily generate a evidence key twosome as well as a self-signed certificate using the make_key
flora inward development/tools
. If yous receive got existing OpenSSL keys yous cannot purpose them equally is however, yous volition take away to convert them using OpenSSL's pkcs8
command:echo "keypwd"|openssl pkcs8 -in mykey.pem -topk8 -outform DER -out mykey.pk8 -passout stdin
Once yous receive got the needed keys, yous tin sign an APK similar this:
$ coffee -jar signapk.jar cert.cer key.pk8 test.apk test-signed.apk
Nothing novel thus far, except the somewhat exotic (but easily parsable past times JCE classes) key format. However, the
signapk
has an extra 'sign whole file' mode, enabled amongst the -w
option. When inward this mode, inward improver to signing each private JAR entry, the tool generates a signature over the whole archive equally well. This trend is non supported past times jarsigner
and is specific to Android. So why sign the whole archive when each of the private files is already signed? In lodge to back upwardly over the air updates (OTA), naturally :). If yous receive got e'er flashed a custom ROM, or been impatient as well as updated your device manually earlier it picked upwardly the official update broadcast, yous know that OTA packages are ZIP files containing the updated files as well as scripts to apply them. It turns out, however, that they a lot to a greater extent than similar JAR files on the inside. They come upwardly amongst a META-INF/
directory, manifests as well as a signature block, plus a few other extras. One of those is the /META-INF/com/android/otacert
file, which contains the update signing certificate (in PEM format). Before booting into recovery to truly apply the update, Android volition verify the bundle signature, thus banking corporation check that the signing certificate is ane that is trusted to sign updates. OTA trusted certificates are completely split upwardly from the 'regular' organisation somewhat boring, thus nosotros volition explore something unlike instead: code signing. This especial aspect of Android has remained virtually unchanged since the start populace release, as well as is thus key to the platform, that is pretty much taken for granted. While neither Java code signing, nor its Android implementation are specially new, some of the finer details are non specially well-known, thus we'll essay to shed some to a greater extent than low-cal on those. The start ship service of the serial volition concentrate on the signature formats used piece the adjacent ane volition facial expression into how code signing fits into Android's security model.Java code signing
As nosotros all know, Android applications are coded (mostly) inward Java, as well as Android application bundle files (APKs) are only weird-looking JARs, thus it pays to sympathise how JAR signing industrial plant first.
First off, a few words nigh code signing inward general. Why would anyone desire to sign code? For the commons reasons: integrity as well as authenticity. Basically, earlier executing whatever third-party programme yous desire to brand for sure that it hasn't been tampered amongst (integrity) as well as that it was truly created past times the entity that it claims to come upwardly from (authenticity). Those features are ordinarily implemented past times some digital signature scheme, which guarantees that only the entity owning the signing key tin create a valid code signature. The signature verification physical care for verifies both that the code has non been tampered amongst as well as that the signature was produced amongst the expected key. One work that code signing doesn't solve direct is whether the code signer (software publisher) tin endure trusted. The commons agency trust is handled is past times requiring the code signer to concur a digital certificate, which they attach to the signed code. Verifiers determine whether to trust the certificate either based on some trust model (e.g., PKI or spider web of trust), or on a case-by-case basis. Another work that code signing does non solve (or trial get to) is whether the signed code is security to run. As nosotros receive got seen, code that has been signed (or appears to be) past times a trusted 3rd political party is non necessarily security (e.g., Flame or trust store, as well as reside inward a, yous guessed it, a ZIP file, ordinarily stored equally
Going dorsum to the original question, if OTA files are JAR files, as well as JAR files don't back upwardly whole-file signatures, where does the signature go? The Android
/system/etc/security/otacerts.zip
. On a production device it volition typically incorporate a unmarried file, probable named releasekey.x509.pem
.Going dorsum to the original question, if OTA files are JAR files, as well as JAR files don't back upwardly whole-file signatures, where does the signature go? The Android
signapk
tool slightly abuses the ZIP format past times adding a null-terminated string comment inward the ZIP comment section, followed past times the binary signature block as well as a 6-byte terminal record, containing the signature offset as well as the size of the entire comment section. This makes it tardily to verify the bundle past times start reading as well as verifying the signature block from the halt of the file, as well as only reading the residuum of the file (which for a major upgrade mightiness endure inward the hundreds of MBs) if the signature checks out. If yous desire to manually verify the bundle signature amongst OpenSSL, yous tin split upwardly the signed information as well as the signature block amongst a script similar the ane below, where the mo declaration is the signature block file, as well as the 3rd ane is the signed ZIP file (without the comments section) to write:#!/bin/env python import bone import sys import struct file_name = sys.argv[1] file_size = os.stat(file_name).st_size f = open(file_name, 'rb') f.seek(file_size - 6) footer = f.read(6) sig_offset = struct.unpack('<H', footer[0:2]) sig_start = file_size - sig_offset[0] sig_size = sig_offset[0] - half dozen f.seek(sig_start) sig = f.read(sig_size) f.seek(0) # 2 bytes comment length + xviii bytes string comment sd = f.read(file_size - sig_offset[0] - 2 - 18) f.close() sf = open(sys.argv[2], 'wb') sf.write(sig) sf.close() zf = open(sys.argv[3], 'wb') zf.write(sd) zf.close()
Summary
Android relies heavily on the Java JAR format, both for application packages (APKs) as well as for organisation updates (OTA packages). APK signing uses a subset of the JAR signing specification equally is, piece OTA packages purpose a custom format that generates a signature over the whole file. Standalone bundle verification tin endure performed amongst measure JDK tools or OpenSSL (after some preprocessing). The Android OS as well as recovery organisation follow the same verification procedures earlier installing APKs or applying organisation updates. In the adjacent article nosotros volition explore how the OS uses bundle signatures as well as how they fit into Android's security model.
Tag :
android security
0 Komentar untuk "Droidcedas : Android Code Signing"