
Security News
Oxlint Introduces Type-Aware Linting Preview
Oxlint’s new preview brings type-aware linting powered by typescript-go, combining advanced TypeScript rules with native-speed performance.
CLI tool (and Ruby API) of easy exporting, encrypting, and decrypting of certificates and private keys. It can also add certificates and private keys to an existing or new keychain :grinning:
Important: The export
command will take control of your "Keychain Access" app so keep all hands off your computer while that command runs
$: exportation export
Name: RokkinCat LLC
Path to save to (default: './'): ./examples
Filename to save as (default: 'export'): dist
Password for private key (default: ''): shhh
Info Take all hands off your computer! exportation is going to take control of 'Keychain Access'
--name
--path
exported.p12
--password
--path
exported.cer
gem install exportation
/System/Library/CoreServices/RemoteManagement/
/Applications/Utilities/
You won't need to give Heroes, Script Editor, or Steam permissions for exportation :wink:
Exportation has three different commands: export
, encrypt
, and decrypt
.
Be lazy! export
uses AppleScript to control the "Keychain Access" app to export a certificate and private to be used for CI (continuous integration) or for other developers.
exportation export --name "Your Company LLC"
Be safe! encrypt
does exactly what it says - it encrypts. It uses AES-256 to encrypt your certificate, private keys and provisioning profiles (any file really) to store safely in your repository for CIs or other developers to access. All files will be appened with a .enc
extension.
exportation encrypt exported.cer exported.p12 --password dudethis
Be awesome! decrypt
decrypts your encrypted files to use on your CI or for other developers to install. BE CAREFUL TO NOT COMMIT THESE BACK INTO YOUR REPO
exportation decrypt exported.cer.enc exported.p12.enc --password dudethis
Exportation::Export.new(
path: "/path/to/export/to",
filename: "base_exported_file_name", #dist.cer and dist.p12
name: "YourCompany LLC",
password: "shhhh"
).run
Exportation::Crypter.new(
files: ["dist.cer","dist.p12"],
password: "shhhh",
output: "./"
).run :en
Exportation::Crypter.new(
files: ["dist.cer.enc","dist.p12.enc"],
password: "shhhh",
output: "./"
).run :de
# Create keychain - name of chain, password, output directory
keychain = Exportation::Keychain.find_or_create_keychain('JoshChain', 'joshiscool', './example')
# Get login keychain
keychain = Exportation::Keychain.login_keychain("password")
# Import a certificate into keychain
keychain.import_certificate './example/dist.cer'
# Import a private key into keychain
keychain.import_private_key './example/dist.p12', 'da_password'
# Unlock keychain
keychain.unlock!
# Adds keychain to search list
keychain.add_to_keychain_list!
# Removes keychain from search list
keychain.remove_keychain_from_list!
In this fastlane
integration, I store my encrypted certificate and private key in the circle
directory (because I'm using CircleCI.
The enc_cert_and_key
lane runs on my local machine where I will export and encrypt the certificate and private key.
The ci_build
can run on my local machine but is meant to run on CircleCI (or TravisCI). This lane decrypts the certifivate and private key from the circle
directory and puts the decrypted files in the build/unenc
directory.
This lane exports the certificate and private key by controling keychain access, encrypts the files, and the removes the unencrypted files.
lane :enc_cert_and_key do
require 'exportation'
# Runs keychain to export cert and private key
Exportation::Export.new(
path: "../circle",
filename: "dist",
name: "RokkinCat LLC",
password: ENV['PKEY_PASSWORD']
).run
# Encrypts cert and private key for repo storage
Exportation::Crypter.new(
files: ["../circle/dist.cer", "../circle/dist.p12"],
password: ENV['ENC_PASSWORD'],
output: "../circle/"
).run :en
# Removes unencrypted cert and private key
sh "rm -f ../circle/dist.cer"
sh "rm -f ../circle/dist.p12"
end
This lane decrypts the certificate and private key, creates the keychain, and imports the certificate and private key into the keychain.
It then uses that keychain the xcodebuild
action to build an archive of the app.
lane :ci_build do
require 'exportation'
enc_password = ENV['ENC_PASSWORD']
keychain_password = ENV['KEYCHAIN_PASSWORD']
private_key_password = ENV['PKEY_PASSWORD']
# Cleaning house and making directories
sh "rm -rf ../build"
sh "mkdir ../build"
sh "mkdir ../build/unenc"
# Decrypting cert and private key
Exportation::Crypter.new(
files: ["../circle/dist.cer.enc", "../circle/dist.p12.enc"],
password: enc_password,
output: "../build/unenc/"
).run :de
# Creating keychain to use for xcodebuild
keychain = Exportation::Keychain.find_or_create_keychain 'ios-build', keychain_password, '../build'
# Importing the Apple certificate and the uncrypted cert and private key
keychain.import_certificate '../circle/apple.cer'
keychain.import_certificate '../build/unenc/dist.cer'
keychain.import_private_key '../build/unenc/dist.p12', private_key_password
# Unlocking keychain (defaults to 1 hour) and adds keychain to user search list
keychain.unlock!
keychain.add_to_keychain_list!
# Building archive
xcodebuild(
clean: true,
archive: true,
archive_path: './build/YourApp.xcarchive',
workspace: ENV['WORKSPACE'],
scheme: ENV['SCHEME'],
configuration: 'Release',
sdk: 'iphoneos',
keychain: keychain.path
)
# Building IPA
xcodebuild(
export_archive: true,
export_path: './build/YourApp'
)
# Send to HockeyApp
hockey({
api_token: ENV['HOCKEYAPP_API_TOKEN'],
})
# Cleaning house again
sh "rm -rf ../circle/unenc"
keychain.remove_keychain_from_list!
end
You shouldn't ever have to do this unless I messed stuff up :)
osacompile -o applescript/exportation.scpt applescript/exportation.applescript
Always put all for arguments in strings because I don't do AppleScript well :grimacing:
osascript applescript/exportation.scpt "~/directory_you_want_to_export_to/" "dist" "iPhone Distribution: Your Company LLC" "thepassword"
Josh Holtz, me@joshholtz.com, @joshdholtz
exportation is available under the MIT license. See the LICENSE file for more info.
FAQs
Unknown package
We found that exportation demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oxlint’s new preview brings type-aware linting powered by typescript-go, combining advanced TypeScript rules with native-speed performance.
Security News
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
Security News
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.