create_cert.sh
· 2.2 KiB · Bash
Raw
#!/usr/bin/env bash
# create_cert.sh — creates a local self-signed Mac code-signing certificate
# Run once. Requires no Apple Developer account.
set -euo pipefail
CERT_NAME="${1:-"Local Mac Developer"}"
KEYCHAIN_NAME="build.keychain"
KEYCHAIN_PASS="keychain_pass" # change this
P12_PASS="p12_pass" # change this
echo "==> Creating build keychain: $KEYCHAIN_NAME"
security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true
security create-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_NAME" 2>/dev/null || true
security set-keychain-settings -lut 21600 "$KEYCHAIN_NAME" # lock after 6 h
security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_NAME"
# Add to keychain search list so tools can find it
security list-keychains -d user -s "$KEYCHAIN_NAME" $(security list-keychains -d user | tr -d '"')
echo "==> Generating self-signed certificate: '$CERT_NAME'"
# Use Keychain Access UI approach (most reliable for self-signed)
cat >/tmp/cert_req.cfg <<EOF
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_req
[ dn ]
CN = $CERT_NAME
[ v3_req ]
keyUsage = digitalSignature
extendedKeyUsage = codeSigning
EOF
# Generate key + cert via openssl, then import
openssl req -x509 -newkey rsa:2048 -days 3650 -nodes \
-keyout /tmp/codesign.key \
-out /tmp/codesign.crt \
-config /tmp/cert_req.cfg
# Bundle into PKCS#12
openssl pkcs12 -export \
-inkey /tmp/codesign.key \
-in /tmp/codesign.crt \
-out /tmp/codesign.p12 \
-passout pass:"$P12_PASS" \
-legacy \
-keypbe PBE-SHA1-3DES \
-certpbe PBE-SHA1-3DES \
-macalg sha1
# Import into build keychain (trust for code signing)
security import /tmp/codesign.p12 \
-k "$KEYCHAIN_NAME" \
-P "$P12_PASS" \
-T /usr/bin/codesign \
-T /usr/bin/security
# Grant codesign permission without UI prompt
security set-key-partition-list \
-S apple-tool:,apple:,codesign: \
-s -k "$KEYCHAIN_PASS" "$KEYCHAIN_NAME"
# Clean up temp files
rm -f /tmp/codesign.key /tmp/codesign.crt /tmp/codesign.p12 /tmp/cert_req.cfg
echo ""
echo "✅ Certificate '$CERT_NAME' created in '$KEYCHAIN_NAME'."
echo " Use this identity string in sign.sh:"
security find-identity -v -p codesigning "$KEYCHAIN_NAME" | grep "$CERT_NAME" | head -1
| 1 | #!/usr/bin/env bash |
| 2 | # create_cert.sh — creates a local self-signed Mac code-signing certificate |
| 3 | # Run once. Requires no Apple Developer account. |
| 4 | |
| 5 | set -euo pipefail |
| 6 | |
| 7 | CERT_NAME="${1:-"Local Mac Developer"}" |
| 8 | KEYCHAIN_NAME="build.keychain" |
| 9 | KEYCHAIN_PASS="keychain_pass" # change this |
| 10 | P12_PASS="p12_pass" # change this |
| 11 | |
| 12 | echo "==> Creating build keychain: $KEYCHAIN_NAME" |
| 13 | |
| 14 | security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true |
| 15 | security create-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_NAME" 2>/dev/null || true |
| 16 | security set-keychain-settings -lut 21600 "$KEYCHAIN_NAME" # lock after 6 h |
| 17 | security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_NAME" |
| 18 | |
| 19 | # Add to keychain search list so tools can find it |
| 20 | security list-keychains -d user -s "$KEYCHAIN_NAME" $(security list-keychains -d user | tr -d '"') |
| 21 | |
| 22 | echo "==> Generating self-signed certificate: '$CERT_NAME'" |
| 23 | # Use Keychain Access UI approach (most reliable for self-signed) |
| 24 | cat >/tmp/cert_req.cfg <<EOF |
| 25 | [ req ] |
| 26 | default_bits = 2048 |
| 27 | prompt = no |
| 28 | default_md = sha256 |
| 29 | distinguished_name = dn |
| 30 | x509_extensions = v3_req |
| 31 | |
| 32 | [ dn ] |
| 33 | CN = $CERT_NAME |
| 34 | |
| 35 | [ v3_req ] |
| 36 | keyUsage = digitalSignature |
| 37 | extendedKeyUsage = codeSigning |
| 38 | EOF |
| 39 | |
| 40 | # Generate key + cert via openssl, then import |
| 41 | openssl req -x509 -newkey rsa:2048 -days 3650 -nodes \ |
| 42 | -keyout /tmp/codesign.key \ |
| 43 | -out /tmp/codesign.crt \ |
| 44 | -config /tmp/cert_req.cfg |
| 45 | |
| 46 | # Bundle into PKCS#12 |
| 47 | openssl pkcs12 -export \ |
| 48 | -inkey /tmp/codesign.key \ |
| 49 | -in /tmp/codesign.crt \ |
| 50 | -out /tmp/codesign.p12 \ |
| 51 | -passout pass:"$P12_PASS" \ |
| 52 | -legacy \ |
| 53 | -keypbe PBE-SHA1-3DES \ |
| 54 | -certpbe PBE-SHA1-3DES \ |
| 55 | -macalg sha1 |
| 56 | |
| 57 | # Import into build keychain (trust for code signing) |
| 58 | security import /tmp/codesign.p12 \ |
| 59 | -k "$KEYCHAIN_NAME" \ |
| 60 | -P "$P12_PASS" \ |
| 61 | -T /usr/bin/codesign \ |
| 62 | -T /usr/bin/security |
| 63 | |
| 64 | # Grant codesign permission without UI prompt |
| 65 | security set-key-partition-list \ |
| 66 | -S apple-tool:,apple:,codesign: \ |
| 67 | -s -k "$KEYCHAIN_PASS" "$KEYCHAIN_NAME" |
| 68 | |
| 69 | # Clean up temp files |
| 70 | rm -f /tmp/codesign.key /tmp/codesign.crt /tmp/codesign.p12 /tmp/cert_req.cfg |
| 71 | |
| 72 | echo "" |
| 73 | echo "✅ Certificate '$CERT_NAME' created in '$KEYCHAIN_NAME'." |
| 74 | echo " Use this identity string in sign.sh:" |
| 75 | security find-identity -v -p codesigning "$KEYCHAIN_NAME" | grep "$CERT_NAME" | head -1 |
| 76 |
sign.sh
· 3.3 KiB · Bash
Raw
#!/usr/bin/env bash
# sign.sh — sign a single binary executable for local use or distribution
# Usage: ./sign.sh path/to/mybinary
set -euo pipefail
# ── CONFIG ────────────────────────────────────────────────────────────────────
BINARY_PATH="${1:?Usage: $0 path/to/mybinary}"
CERT_IDENTITY="Local Mac Developer" # must match CN in create_cert.sh
# for real Apple certs use:
# "Developer ID Application: Your Name (TEAMID)"
KEYCHAIN_PATH="build.keychain-db"
KEYCHAIN_PASS="build_keychain_password" # must match create_cert.sh
# For notarization (optional, set NOTARIZE=true to enable):
NOTARIZE=false
APPLE_ID="longnghia2.00@gmail.com"
APPLE_TEAM_ID="PaulCoding"
APPLE_APP_PASSWORD="some_password" # app-specific password from appleid.apple.com
# ── END CONFIG ────────────────────────────────────────────────────────────────
if [ ! -f "$BINARY_PATH" ]; then
echo "❌ File not found: $BINARY_PATH"
exit 1
fi
BINARY_NAME="$(basename "$BINARY_PATH")"
ZIP_PATH="$(dirname "$BINARY_PATH")/${BINARY_NAME}.zip"
echo "==> Unlocking build keychain"
security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_PATH"
security list-keychains -d user -s "$KEYCHAIN_PATH" \
$(security list-keychains -d user | tr -d '"')
# ── Sign ──────────────────────────────────────────────────────────────────────
echo "==> Signing binary: $BINARY_NAME"
codesign --sign "$CERT_IDENTITY" \
--keychain "$KEYCHAIN_PATH" \
--timestamp \
--options runtime \
--force \
"$BINARY_PATH"
# ── Verify ────────────────────────────────────────────────────────────────────
echo "==> Verifying signature"
codesign --verify --strict --verbose=4 "$BINARY_PATH"
echo "==> Signature details"
codesign --display --verbose=4 "$BINARY_PATH" 2>&1
echo "==> Gatekeeper assessment (self-signed certs will show 'rejected' — expected)"
spctl --assess --type execute --verbose "$BINARY_PATH" 2>&1 || true
# ── Optional: notarize ────────────────────────────────────────────────────────
if [ "$NOTARIZE" = "true" ]; then
echo "==> Zipping binary for notarization submission"
ditto -c -k --keepParent "$BINARY_PATH" "$ZIP_PATH"
echo "==> Submitting to Apple notary service"
xcrun notarytool submit "$ZIP_PATH" \
--apple-id "$APPLE_ID" \
--team-id "$APPLE_TEAM_ID" \
--password "$APPLE_APP_PASSWORD" \
--wait
echo "==> Stapling notarization ticket"
xcrun stapler staple "$BINARY_PATH"
xcrun stapler validate "$BINARY_PATH"
rm -f "$ZIP_PATH"
fi
echo ""
echo "✅ Done: $BINARY_PATH"
codesign -dv "$BINARY_PATH" 2>&1 | grep -E "^(Authority|TeamIdentifier|Signature size|Hash|CDHash)"
| 1 | #!/usr/bin/env bash |
| 2 | # sign.sh — sign a single binary executable for local use or distribution |
| 3 | # Usage: ./sign.sh path/to/mybinary |
| 4 | |
| 5 | set -euo pipefail |
| 6 | |
| 7 | # ── CONFIG ──────────────────────────────────────────────────────────────────── |
| 8 | BINARY_PATH="${1:?Usage: $0 path/to/mybinary}" |
| 9 | CERT_IDENTITY="Local Mac Developer" # must match CN in create_cert.sh |
| 10 | # for real Apple certs use: |
| 11 | # "Developer ID Application: Your Name (TEAMID)" |
| 12 | KEYCHAIN_PATH="build.keychain-db" |
| 13 | KEYCHAIN_PASS="build_keychain_password" # must match create_cert.sh |
| 14 | |
| 15 | # For notarization (optional, set NOTARIZE=true to enable): |
| 16 | NOTARIZE=false |
| 17 | APPLE_ID="longnghia2.00@gmail.com" |
| 18 | APPLE_TEAM_ID="PaulCoding" |
| 19 | APPLE_APP_PASSWORD="some_password" # app-specific password from appleid.apple.com |
| 20 | # ── END CONFIG ──────────────────────────────────────────────────────────────── |
| 21 | |
| 22 | if [ ! -f "$BINARY_PATH" ]; then |
| 23 | echo "❌ File not found: $BINARY_PATH" |
| 24 | exit 1 |
| 25 | fi |
| 26 | |
| 27 | BINARY_NAME="$(basename "$BINARY_PATH")" |
| 28 | ZIP_PATH="$(dirname "$BINARY_PATH")/${BINARY_NAME}.zip" |
| 29 | |
| 30 | echo "==> Unlocking build keychain" |
| 31 | security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_PATH" |
| 32 | security list-keychains -d user -s "$KEYCHAIN_PATH" \ |
| 33 | $(security list-keychains -d user | tr -d '"') |
| 34 | |
| 35 | # ── Sign ────────────────────────────────────────────────────────────────────── |
| 36 | echo "==> Signing binary: $BINARY_NAME" |
| 37 | codesign --sign "$CERT_IDENTITY" \ |
| 38 | --keychain "$KEYCHAIN_PATH" \ |
| 39 | --timestamp \ |
| 40 | --options runtime \ |
| 41 | --force \ |
| 42 | "$BINARY_PATH" |
| 43 | |
| 44 | # ── Verify ──────────────────────────────────────────────────────────────────── |
| 45 | echo "==> Verifying signature" |
| 46 | codesign --verify --strict --verbose=4 "$BINARY_PATH" |
| 47 | |
| 48 | echo "==> Signature details" |
| 49 | codesign --display --verbose=4 "$BINARY_PATH" 2>&1 |
| 50 | |
| 51 | echo "==> Gatekeeper assessment (self-signed certs will show 'rejected' — expected)" |
| 52 | spctl --assess --type execute --verbose "$BINARY_PATH" 2>&1 || true |
| 53 | |
| 54 | # ── Optional: notarize ──────────────────────────────────────────────────────── |
| 55 | if [ "$NOTARIZE" = "true" ]; then |
| 56 | echo "==> Zipping binary for notarization submission" |
| 57 | ditto -c -k --keepParent "$BINARY_PATH" "$ZIP_PATH" |
| 58 | |
| 59 | echo "==> Submitting to Apple notary service" |
| 60 | xcrun notarytool submit "$ZIP_PATH" \ |
| 61 | --apple-id "$APPLE_ID" \ |
| 62 | --team-id "$APPLE_TEAM_ID" \ |
| 63 | --password "$APPLE_APP_PASSWORD" \ |
| 64 | --wait |
| 65 | |
| 66 | echo "==> Stapling notarization ticket" |
| 67 | xcrun stapler staple "$BINARY_PATH" |
| 68 | xcrun stapler validate "$BINARY_PATH" |
| 69 | |
| 70 | rm -f "$ZIP_PATH" |
| 71 | fi |
| 72 | |
| 73 | echo "" |
| 74 | echo "✅ Done: $BINARY_PATH" |
| 75 | codesign -dv "$BINARY_PATH" 2>&1 | grep -E "^(Authority|TeamIdentifier|Signature size|Hash|CDHash)" |
| 76 |