android-keystore-generation

Generate production and local development keystores for Android release signing

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "android-keystore-generation" with this command: npx skills add hitoshura25/claude-devtools/hitoshura25-claude-devtools-android-keystore-generation

Android Keystore Generation

Generates dual keystores for Android release signing: production (CI/CD only) and local development.

Prerequisites

  • JDK installed (keytool command available)
  • Write access to project directory

Inputs

InputRequiredDefaultDescription
project_pathYes.Android project root
organizationYes-Organization name for certificate DN
country_codeNoUS2-letter country code

Process

Organization Name

ALWAYS prompt the user, but provide the auto-detected value as default.

Step 1: Detect organization from package name

# Extract package name from build.gradle.kts
PACKAGE=$(grep "applicationId" app/build.gradle.kts | sed 's/.*"\(.*\)".*/\1/')
echo "Package: $PACKAGE"

# Extract second segment: com.{ORG}.app → ORG
ORG=$(echo $PACKAGE | cut -d. -f2)
echo "Detected organization: $ORG"

Step 2: MANDATORY - Ask the user for confirmation

DO NOT SKIP THIS PROMPT

Ask the user:

"The detected organization name is {ORG}. Press Enter to use this, or type a different name:"

Wait for user response. Use their input if provided, otherwise use the detected default.

Step 3: Store the confirmed organization name

ORGANIZATION="{confirmed_org_name}"
echo "Using organization: $ORGANIZATION"

Why this matters: The organization appears in the certificate's Distinguished Name. While it doesn't affect app functionality, users may want to customize it.

Password Generation Options

Choose one option for keystore passwords:

Option 1 (Recommended): User-Provided Password

Ask the user to provide a password for the production keystore:

"Please enter a password for the production keystore (minimum 12 characters, mix of letters, numbers, and symbols):"

Security benefits:

  • Password never visible to the agent during the conversation
  • User has complete control over password strength and storage
  • Reduces risk of password exposure in logs or conversation history

Instructions for user:

# User will run keytool command manually with their chosen password
# Example:
keytool -genkeypair -v \
  -keystore keystores/production-release.jks \
  -storetype PKCS12 \
  -alias upload \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000 \
  -storepass "YOUR_PASSWORD_HERE" \
  -keypass "YOUR_PASSWORD_HERE" \
  -dname "CN=Android Release, OU=Android, O={ORGANIZATION}, C=US"

Option 2: Generated Password

If the user prefers a generated password, use the automated generation steps below.

Note: The agent will have access to this password during the session. The password will be stored in temporary files and KEYSTORE_INFO.txt.

"Would you like me to generate a secure password? (The agent will see this password during generation)"

If yes, proceed with the automated generation steps.

Step 1: Create Keystores Directory

mkdir -p keystores

Step 2: Generate Production Keystore

SECURITY: This keystore is for CI/CD only. Never use locally.

⚠️ IMPORTANT: Run each command in a SEPARATE bash call. Do NOT combine commands.

Step 2a: Generate password and save to file

openssl rand -base64 24 | tr -d '/+=' | head -c 24 > /tmp/prod_password.txt

Step 2b: Read and display the password

cat /tmp/prod_password.txt

📝 Copy this password now - you'll need it for the keytool command and KEYSTORE_INFO.txt

Step 2c: Generate the keystore

Replace {PASSWORD} with the password from Step 2b, and {ORGANIZATION} with the confirmed organization name:

keytool -genkeypair -v \
  -keystore keystores/production-release.jks \
  -storetype PKCS12 \
  -alias upload \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000 \
  -storepass "{PASSWORD}" \
  -keypass "{PASSWORD}" \
  -dname "CN=Android Release, OU=Android, O={ORGANIZATION}, C=US"

If keytool prompts for confirmation, type yes and press Enter.

Step 2d: Verify keystore was created

ls -la keystores/production-release.jks

Expected output:

-rw-------  1 user  staff  2557 Dec 11 10:30 keystores/production-release.jks

Step 3: Generate Local Development Keystore

⚠️ IMPORTANT: Run each command in a SEPARATE bash call. Do NOT combine commands.

Step 3a: Generate password and save to file

openssl rand -base64 24 | tr -d '/+=' | head -c 24 > /tmp/local_password.txt

Step 3b: Read and display the password

cat /tmp/local_password.txt

📝 Copy this password now - you'll need it for the keytool command and KEYSTORE_INFO.txt

Step 3c: Generate the keystore

Replace {PASSWORD} with the password from Step 3b:

keytool -genkeypair -v \
  -keystore keystores/local-dev-release.jks \
  -storetype PKCS12 \
  -alias local-dev \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000 \
  -storepass "{PASSWORD}" \
  -keypass "{PASSWORD}" \
  -dname "CN=Local Development, OU=Development, O=Local, C=US"

If keytool prompts for confirmation, type yes and press Enter.

Step 3d: Verify keystore was created

ls -la keystores/local-dev-release.jks

Expected output:

-rw-------  1 user  staff  2557 Dec 11 10:30 keystores/local-dev-release.jks

Step 4: Create Credentials File

cat > keystores/KEYSTORE_INFO.txt << EOF
Production Keystore
===================
File: production-release.jks
Alias: upload
Store Password: $PROD_PASSWORD
Key Password: $PROD_PASSWORD (same as store - PKCS12 requirement)

⚠️ SECURITY: CI/CD ONLY - Never use on developer machines

GitHub Secrets:
  SIGNING_KEY_STORE_BASE64: $(base64 -w 0 keystores/production-release.jks 2>/dev/null || base64 -i keystores/production-release.jks)
  SIGNING_KEY_ALIAS: upload
  SIGNING_STORE_PASSWORD: $PROD_PASSWORD
  SIGNING_KEY_PASSWORD: $PROD_PASSWORD

---

Local Development Keystore
==========================
File: local-dev-release.jks
Alias: local-dev
Store Password: $LOCAL_PASSWORD
Key Password: $LOCAL_PASSWORD

Add to ~/.gradle/gradle.properties:
  SIGNING_KEY_STORE_PATH=$(pwd)/keystores/local-dev-release.jks
  SIGNING_KEY_ALIAS=local-dev
  SIGNING_STORE_PASSWORD=$LOCAL_PASSWORD
  SIGNING_KEY_PASSWORD=$LOCAL_PASSWORD
EOF

Step 5: Update .gitignore

# Add to .gitignore if not present
grep -q "keystores/" .gitignore 2>/dev/null || echo "keystores/" >> .gitignore
grep -q "*.jks" .gitignore 2>/dev/null || echo "*.jks" >> .gitignore

Verification

MANDATORY: Run these commands:

# Verify keystores exist
ls -la keystores/*.jks

# Verify credentials documented
cat keystores/KEYSTORE_INFO.txt

# Verify gitignored
grep "keystores" .gitignore

Expected output:

  • Two .jks files in keystores/
  • KEYSTORE_INFO.txt with passwords
  • keystores/ in .gitignore

Outputs

OutputLocationDescription
Production keystorekeystores/production-release.jksFor CI/CD only
Local keystorekeystores/local-dev-release.jksFor local testing
Credentialskeystores/KEYSTORE_INFO.txtPasswords and setup info

Troubleshooting

"keytool: command not found"

Cause: JDK not installed or not in PATH Fix: Install JDK 17: brew install openjdk@17 (macOS) or apt install openjdk-17-jdk (Linux)

"openssl: command not found"

Cause: OpenSSL not installed Fix: Use alternative password generation: head -c 24 /dev/urandom | base64

Completion Criteria

  • keystores/production-release.jks exists
  • keystores/local-dev-release.jks exists
  • keystores/KEYSTORE_INFO.txt exists with passwords
  • keystores/ is in .gitignore

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

android-playstore-setup

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

android-playstore-scan

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

android-proguard-setup

No summary provided by upstream source.

Repository SourceNeeds Review
android-keystore-generation | V50.AI