Encrypt files and folders with AES-256 on OSX
Motivation
Some of our users need to be able to send each other files which contain sensitive data. The solution have to be easy to use, or otherwise they will not use it. To be able to exchange files with other platforms there also is a demand that the encryption used is AES-256.
Fine, our os have a built in option "Compress
Planning
To be able to get my own elements in the right-click menu I can create a Automator service which takes selected elements from Finder as input and pass them through the workflow, great!
But how can I create encrypted archives on osx?
$ zip
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]
The default action is to add or replace zipfile entries from list, which
can include the special name - to compress standard input.
If zipfile and list are omitted, zip compresses stdin to stdout.
-f freshen: only changed files -u update: only changed or new files
-d delete entries in zipfile -m move into zipfile (delete OS files)
-r recurse into directories -j junk (don't record) directory names
-0 store only -l convert LF to CR LF (-ll CR LF to LF)
-1 compress faster -9 compress better
-q quiet operation -v verbose operation/print version info
-c add one-line comments -z add zipfile comment
-@ read names from stdin -o make zipfile as old as latest entry
-x exclude the following names -i include only the following names
-F fix zipfile (-FF try harder) -D do not add directory entries
-A adjust self-extracting exe -J junk zipfile prefix (unzipsfx)
-T test zipfile integrity -X eXclude eXtra file attributes
-y store symbolic links as the link instead of the referenced file
-e encrypt -n don't compress these suffixes
-h2 show more help
It seems that -e actually wil encrypt the archive for me, maybe I can script something around that? But first I want to see what encryption is actually is offering me.
$ man zip
No mention of ciphers there, but luckily zip belongs to the bits & pieces of osx that is opensource. Lets look into the source code and see if we can get some hints there.
*
This encryption code is a direct transcription of the algorithm from
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
file (appnote.txt) is distributed with the PKZIP program (even in the
version without encryption capabilities).
*/
if this is true, then this is not AES-256, which again means I cant use the built in zip.
After searching the Internet, I decided to give the commandline version of 7-zip a try. According to their documentation it supports AES-256. Which is exactly what I need.
Implementation
So the next step now is to actually install the commandline version of 7-zip, which I do with MacPorts.
$ port search p7zip
p7zip @9.38.1 (archivers)
7-Zip implementation
$ sudo port install p7zip
But since I am going to distribute this to multiple machines I want to compile the p7zip port to an distributable pkg so I can deploy them with Munki. I have done this before with Curl, so I just followed my own documentation and created a p7zip.pkg.
Remember that you have to compile the p7zip port for each version of osx you are going to deploy to, i.e 10.8, 10.9 and 10.10.
When the p7zip.pkg is installed I can compress and encrypt files by doing:
7za a "archive.zip" "inputfile" -tzip -mem=AES256 -mx9 -p"password"
Make it userfriendly
I now have capabilities to compress and encrypt files, using AES-256. The last piece of the puzzle is to make it a bit more userfriendly as described earlier.
For this I need an applescript snippet to capture the password, and a shell snippet to do the compression with the supplied password.
Applescript:
on run {input, parameters}
tell application "System Events"
display dialog "Password:" default answer "" with hidden answer
end tell
set pass to text returned of result
return input & pass
end run
Bash:
# Get the password
password=`echo "${@: -1}"`
# Clean out the password (which is the last element in the input parameter list
set -- "${@:1:$(($#-1))}"
# Loop over all files and folders and compress them with the given password
for f in "$@"
do
if [ -d "$f" ]; then
/opt/uib/p7zip/bin/7za a "$f.zip" "$f" -tzip -mem=AES256 -mx9 -p"$password"
fi
if [ ! -d "$f" ]; then
/opt/uib/p7zip/bin/7za a "$f.zip" "$f" -tzip -mem=AES256 -mx9 -p"$password"
fi
done
Chain with Automator:
Conclusion
By combining different tools I managed to get what I needed. The hardest part was debuging the various Automator approaches I tested.