#!/usr/bin/env bash # vim:sw=2:sts=2:expandtab error_exit() { echo error_exit exit } echo_stderr() { echo $@ 1>&1 } usage() { echo_stderr "Usage: $0 -k ssh_public_key -f file" exit } file_does_not_exist() { echo_stderr "$1 does not exist or not a regular file" exit } # 引数解析 if [ $# -lt 4 ] then usage fi while getopts f:k:h OPTION do case ${OPTION} in f) if [ -f "${OPTARG}" ] then INPUT_FILE=$(readlink -f "${OPTARG}") else file_does_not_exist "${OPTARG}" fi ;; k) if [ -f "${OPTARG}" ] then SSH_PUBKEY=$(readlink -f "${OPTARG}") else file_does_not_exist "${OPTARG}" fi ;; h) usage ;; '?') usage ;; esac done umask 077 MAGICNUMBER=46f5c833d3f02bfa476dc62215484d275bc848f71c164236e35db9766a9f2a8d # 作業用ディレクトリ TMPDIR=$(mktemp -d) AES_KEY=${TMPDIR}/key.bin SSH_PUBKEY_PKCS8=${TMPDIR}/ssh_pubkey.pkcs8 INPUT_FILE_BASENAME=$(basename "${INPUT_FILE}") ARCHIVE_DIR=${TMPDIR}/${MAGICNUMBER} ENCRYPTED_FILE=${ARCHIVE_DIR}/encrypted_data.bin ENCRYPTED_AES_KEY=${ARCHIVE_DIR}/encrypted_key.bin echo ${TMPDIR} # debug ( cd ${TMPDIR} # アーカイブ先ディレクトリを作成 mkdir -p ${ARCHIVE_DIR} echo ${INPUT_FILE_BASENAME} > ${ARCHIVE_DIR}/originalfilename # 相手のSSH鍵をPKCS8形式に変換 ssh-keygen -e -m PKCS8 -f ${SSH_PUBKEY} > ${SSH_PUBKEY_PKCS8} || error_exit # 共通鍵を生成して相手のSSH公開鍵で暗号化したものをbase64エンコードする dd if=/dev/urandom bs=4k count=1 | \ openssl base64 -e | head -1 | tee ${AES_KEY} | \ openssl rsautl -encrypt -pubin -inkey ${SSH_PUBKEY_PKCS8} | \ openssl base64 -e > ${ENCRYPTED_AES_KEY}.base64 # 対象のファイルを共通鍵で暗号化 openssl enc -aes-128-cbc -e -a -kfile ${AES_KEY} -in ${INPUT_FILE} -out ${ENCRYPTED_FILE} shar $(find $(basename ${ARCHIVE_DIR})) | sed -e 's|^exit$||' > ${INPUT_FILE_BASENAME%.*}.shar ) ### ここから復号スクリプト DECRYPT_SCRIPT_PART1='#!/usr/bin/env bash echo_stderr() { echo $@ 1>&1 } usage() { echo_stderr "Usage: $0 -k ssh_private_key" exit } file_does_not_exist() { echo_stderr "$1 does not exist or not a regular file" exit } # 引数解析 if [ $# -lt 2 ] then usage fi while getopts k:h OPTION do case ${OPTION} in k) if [ -f "${OPTARG}" ] then SSH_PRIVKEY=$(readlink -f "${OPTARG}") else file_does_not_exist "${OPTARG}" fi ;; h) usage ;; \?) usage ;; esac done MAGICNUMBER=46f5c833d3f02bfa476dc62215484d275bc848f71c164236e35db9766a9f2a8d ' DECRYPT_SCRIPT_PART2=' ORIGINAL_FILENAME="$(cat ${MAGICNUMBER}/originalfilename)" ( cd ${MAGICNUMBER} # 暗号化共通鍵をbase64デコード openssl base64 -d -in encrypted_key.bin.base64 -out encrypted_key.bin # 暗号化した鍵を自分のSSH秘密鍵で復号 openssl rsautl -decrypt -inkey ${SSH_PRIVKEY} -in encrypted_key.bin -out decrypted_key.bin # 復号した鍵でファイルを復号 openssl enc -aes-128-cbc -d -a -kfile decrypted_key.bin -in encrypted_data.bin -out "$(cat originalfilename)" ) cp -i -a \ "${MAGICNUMBER}/${ORIGINAL_FILENAME}" \ "${ORIGINAL_FILENAME}" if [ -d "${MAGICNUMBER}" ] then rm -rf "${MAGICNUMBER}" fi ' echo "${DECRYPT_SCRIPT_PART1}" > ${TMPDIR}/__${INPUT_FILE_BASENAME}__.shar cat ${TMPDIR}/${INPUT_FILE_BASENAME%.*}.shar >> ${TMPDIR}/__${INPUT_FILE_BASENAME}__.shar echo "${DECRYPT_SCRIPT_PART2}" >> ${TMPDIR}/__${INPUT_FILE_BASENAME}__.shar cp -i -a ${TMPDIR}/__${INPUT_FILE_BASENAME}__.shar ./${INPUT_FILE_BASENAME}.bash if [ -d "${TMPDIR}" ] then # TODO rm -rf rm -ri "${TMPDIR}" fi