Skip to content

caffeine-soft/android-signer

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

84 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Android Signer

A pure-Rust library and CLI tool for parsing and signing Android App Bundles (.aab) and Android Packages (.apk).

This repository is a refactored and modernized fork of google/pack, decomposed into a Cargo workspace consisting of two crates:

  • android-signer-cli: A standalone, statically-compiled command-line tool.
  • android-signer-lib: A reusable Rust library crate for integrating Android signing capabilities into your own applications.

Usage (CLI)

You can download pre-compiled binaries from the Releases page for Windows, macOS, and Linux.

The CLI takes an input archive, a keystore file (.p12 or .pem), and the keystore password, then outputs a signed archive containing the appropriate signatures (v1 for .aab, v2/v3 for .apk).

android-signer-cli --input app-release-unsigned.aab \
                   --output app-release-signed.aab \
                   --keystore my-release-key.p12 \
                   --password my-super-secret-password

By default it will look for keystore.p12 and use password as the password.

Supported Build Targets

  • x86_64-unknown-linux-musl
  • aarch64-unknown-linux-musl
  • x86_64-apple-darwin
  • aarch64-apple-darwin
  • x86_64-pc-windows-msvc

Usage (Library)

Add android-signer-lib to your Cargo.toml.

[dependencies]
android-signer-lib = "0.1"

Then you can use it in your code as follows:

use android_signer_lib::{crypto_keys::Keys, sign_apk_buffer, sign_aab_buffer};
use std::fs;

fn sign_my_app() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Load Keys
    let p12_bytes = fs::read("my_keystore.p12")?;
    let keys = Keys::from_p12(&p12_bytes, "my_password")?;

    // 2. Read App Buffer
    let mut apk_buf = fs::read("unsigned.apk")?;
    let aab_buf = fs::read("unsigned.aab")?;

    // 3. Sign Archive (APK uses v2/v3, AAB uses v1)
    let signed_apk = sign_apk_buffer(&mut apk_buf, &keys)?;
    let signed_aab = sign_aab_buffer(&aab_buf, &keys)?;
    
    // 4. Save
    fs::write("signed.apk", signed_apk)?;
    fs::write("signed.aab", signed_aab)?;
    Ok(())
}

Usage in GitHub Actions

Below is an example of how to use the android-signer-cli to sign an .aab file using a PEM-encoded keystore stored in GitHub Secrets.

    - name: Download android-signer-cli
      run: |
        wget [https://github.com/caffeine-soft/android-signer/releases/download/v0.1.1/android-signer-cli-x86_64-unknown-linux-musl](https://github.com/caffeine-soft/android-signer/releases/download/v0.1.1/android-signer-cli-x86_64-unknown-linux-musl) -O android-signer-cli
      
    - name: Grant execute permission for android-signer-cli
      run: chmod +x android-signer-cli

    - name: Prepare PEM Keystore
      run: printf "%s" "${{ secrets.KEYSTORE_PEM_BASE64 }}" | base64 -di > keystore.pem

    - name: Sign AAB
      run: |
        ./android-signer-cli \
          --input unsigned-aab-${{ needs.prepare.outputs.new_tag }}.aab \
          --output gmsl-release-${{ needs.prepare.outputs.new_tag }}.aab \
          --keystore keystore.pem

    - name: Clean up Keystore
      if: always()
      run: rm -f keystore.pem

Setting up secrets.KEYSTORE_PEM_BASE64

The android-signer-cli expects a "combined" PEM file containing both your certificate and private key.

1. Create a Combined PEM

If you have a .p12 file, convert it using OpenSSL:

# Extract private key
openssl pkcs12 -in cert.p12 -nocerts -nodes -out key.pem
# Extract certificate
openssl pkcs12 -in cert.p12 -clcerts -nokeys -out cert.pem
# Combine
cat cert.pem key.pem > combined.pem

2. Encode to Base64

Encode the combined.pem file to a string to store it in GitHub Secrets:

macOS/Linux:

 base64 -i combined.pem | pbcopy

Windows (PowerShell):

[Convert]::ToBase64String([IO.File]::ReadAllBytes("combined.pem")) | clip

3. Add to GitHub

Navigate to Settings > Secrets and variables > Actions in your repository and add a new secret named KEYSTORE_PEM_BASE64 with the copied string as the value.

Features

  • Zero dependencies on the Android SDK, Java, or apksigner.
  • Computes APK Signature Scheme v2 and v3 blocks directly.
  • Handles both .apk and .aab file structures natively.

License

Apache License 2.0

About

πŸ€–β†’πŸ“¦ | Pack Android Resources into APKs/AABs from WebAssembly without Studio or the SDK

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Rust 100.0%