Skip to content

Commit 4c193bb

Browse files
committed
Generate minimal ecc certificate on the fly
1 parent 9358802 commit 4c193bb

File tree

7 files changed

+136
-12
lines changed

7 files changed

+136
-12
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ApkGolf
2-
This repository hosts the smallest Android APK in the world. The current size of the APK is *678 bytes*.
2+
This repository hosts the smallest Android APK in the world. The current size of the APK is *677 bytes*.
33

44
To learn more about how this was achieved, please read the [blog post](https://fractalwrench.co.uk/posts/playing-apk-golf-how-low-can-an-android-app-go/).
55

@@ -34,8 +34,8 @@ Further byte-level optimisation of what remains of the manifest.
3434

3535
Contributed by [Madis Pink](https://github.com/madisp) in this [Pull Request](https://github.com/fractalwrench/ApkGolf/pull/6)
3636

37-
## Minimising APK Signing Certificate (678 bytes, 18% reduction)
37+
## Minimising APK Signing Certificate (677 bytes, 18% reduction)
3838
Manual removal of unnecessary fields present in the certificate used to sign the APK.
3939

4040
Contributed by [klyubin](https://github.com/klyubin) in this [Pull Request](https://github.com/fractalwrench/ApkGolf/pull/15)
41-
41+
Automated by [Adam Yi](https://github.com/adamyi)

build.sh

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#!/usr/bin/env bash
22

3-
set -e
4-
53
rm -rf build
64
mkdir -p build/apk
75

@@ -18,6 +16,41 @@ recompress() {
1816

1917
set -x
2018

19+
echo "Compiling certificate generation program"
20+
21+
success=0
22+
23+
gcc -o build/generate_cert generate_cert.c -lssl -lcrypto -ldl
24+
25+
if [ $? -eq 0 ]; then
26+
echo "Generating cert"
27+
cd build
28+
./generate_cert
29+
if [ $? -eq 0 ]; then
30+
cd ..
31+
openssl x509 -in build/cert.pem -noout -text
32+
if [ $? -eq 0 ]; then
33+
openssl pkcs8 -topk8 -in build/key.pem -out build/key.pk8 -outform DER -nocrypt
34+
if [ $? -eq 0 ]; then
35+
echo "Success"
36+
success=1
37+
fi
38+
fi
39+
else
40+
cd ..
41+
fi
42+
fi
43+
44+
if [ $success -eq 0 ]; then
45+
echo "Failed to generate cert. Using pre-generated cert."
46+
rm build/cert.pem
47+
rm build/key.pk8
48+
cp cert.pem build/
49+
cp key.pk8 build/
50+
fi
51+
52+
set -e
53+
2154
echo "Creating base apk"
2255
cp app/AndroidManifest.xml build/apk/
2356

@@ -27,7 +60,7 @@ zip -j -r build/app-unsigned.apk build/apk
2760
recompress build/app-unsigned.apk
2861

2962
echo "Signing archive"
30-
$ANDROID_HOME/build-tools/26.0.2/apksigner sign --v1-signing-enabled false --key key.pk8 --cert key.x509.pem --in build/app-unsigned.apk --out build/signed-release.apk --min-sdk-version 24
63+
$ANDROID_HOME/build-tools/26.0.2/apksigner sign --v1-signing-enabled false --key build/key.pk8 --cert build/cert.pem --in build/app-unsigned.apk --out build/signed-release.apk --min-sdk-version 24
3164

3265
set +x
3366

cert.pem

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIGgMIGVAgEBMAMGAQAwCTEHMAUGAQATADAaFwswMDAxMDEwMDAwWhcLMDAwMTAx
3+
MDAwMFowCTEHMAUGAQATADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOYMo2Ld
4+
mbwCoefiz7NRQ+du9obnpJNhRK11XPZHhk6jSRdFiOkqMhko2YI/XWlq6BkC3OPS
5+
r3QkiEeT3i+EXj8wAwYBAAMBAA==
6+
-----END CERTIFICATE-----

generate_cert.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Generate minimal ECC cert
2+
// Required OpenSSL version < 1.0.1i
3+
// author: Adam Yi <[email protected]>
4+
5+
#include <stdio.h>
6+
7+
#include <openssl/pem.h>
8+
#include <openssl/x509.h>
9+
#include <openssl/asn1.h>
10+
11+
EVP_PKEY * generate_key_ecc()
12+
{
13+
BIO *outbio = NULL;
14+
15+
int eccgrp = OBJ_txt2nid("prime256v1");
16+
EC_KEY *myecc = EC_KEY_new_by_curve_name(eccgrp);
17+
18+
//EC_KEY_set_asn1_flag(myecc, OPENSSL_EC_NAMED_CURVE);
19+
EC_KEY_set_asn1_flag(myecc, 1);
20+
21+
if (! (EC_KEY_generate_key(myecc)))
22+
BIO_printf(outbio, "Error generating the ECC key.");
23+
24+
EVP_PKEY *pkey = EVP_PKEY_new();
25+
if (!EVP_PKEY_assign_EC_KEY(pkey, myecc))
26+
BIO_printf(outbio, "Error assigning ECC key to EVP_PKEY structure.");
27+
28+
return pkey;
29+
}
30+
31+
X509 * generate_x509(EVP_PKEY * pkey)
32+
{
33+
X509 * x509 = X509_new();
34+
35+
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
36+
37+
ASN1_TIME_set_string(X509_get_notBefore(x509), "0001010000Z");
38+
ASN1_TIME_set_string(X509_get_notAfter(x509), "0001010000Z");
39+
40+
X509_set_pubkey(x509, pkey);
41+
42+
// X509v1 cannot have empty issuer & subject DN
43+
X509_NAME * name = X509_get_subject_name(x509);
44+
45+
X509_NAME_add_entry_by_NID(name, 0, V_ASN1_APP_CHOOSE, "", 0, 0, 0);
46+
47+
X509_set_issuer_name(x509, name);
48+
49+
return x509;
50+
}
51+
52+
void write_to_disk(EVP_PKEY * pkey, X509 * x509)
53+
{
54+
FILE * pkey_file = fopen("key.pem", "wb");
55+
56+
PEM_write_PKCS8PrivateKey(pkey_file, pkey, NULL, NULL, 0, NULL, NULL);
57+
fclose(pkey_file);
58+
59+
FILE * x509_file = fopen("cert.pem", "wb");
60+
61+
PEM_write_X509(x509_file, x509);
62+
fclose(x509_file);
63+
64+
return;
65+
}
66+
67+
int main(int argc, char ** argv)
68+
{
69+
printf("Generating ECC key...\n");
70+
71+
EVP_PKEY * pkey = generate_key_ecc();
72+
if(!pkey)
73+
return 1;
74+
75+
printf("Generating X509 cert...\n");
76+
77+
X509 * x509 = generate_x509(pkey);
78+
if(!x509)
79+
{
80+
EVP_PKEY_free(pkey);
81+
return 1;
82+
}
83+
84+
printf("Writting files....\n");
85+
86+
write_to_disk(pkey, x509);
87+
EVP_PKEY_free(pkey);
88+
X509_free(x509);
89+
90+
printf("Done!\n");
91+
}

key.pk8

71 Bytes
Binary file not shown.

key.x509.pem

Lines changed: 0 additions & 6 deletions
This file was deleted.

signed-release.apk

-1 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)