-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathenc
executable file
·183 lines (160 loc) · 5.81 KB
/
enc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/usr/bin/env sh
# =============================================================================
# 軽量ファイルの暗号化スクリプト (UTF-8)
# =============================================================================
#
# GitHub 上で公開されている(https://github.com/<user name>.keys で取得できる)
# 相手の RSA 公開鍵を使って小さなファイルを暗号化します。
#
# - 使い方の例:
# 以下のコマンドで暗号化された'himitsu.txt.enc' が作成されます。
# $ ./enc.sh KEINOS ./himitsu.txt
#
# - 注意:利用前にスクリプトに実行権限を与えるのを忘れないでください。
# -----------------------------------------------------------------------------
# Requirement check
# -----------------------------------------------------------------------------
if ! type openssl 2>/dev/null 1>/dev/null; then
echo >&2 '暗号化に必要な openssl コマンドがインストールされていません。'
exit 1
fi
if ! type ssh-keygen 2>/dev/null 1>/dev/null; then
echo >&2 'ssh-keygen コマンド(openssh)がインストールされていません。'
exit 1
fi
# -----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------
# ヘルプ表示
# ----------------
if [ $# -lt 2 ]; then
echo
echo "使い方: $0 <github user> <input file> [<output file>]"
echo
echo "- <github user> : 相手の GitHub アカウント名"
echo "- <input file> : 暗号化したいファイルのパス"
echo "[オプション]"
echo "- <output file> : 暗号化されたファイルの出力先のパス"
echo " 指定がない場合は <input_file>.enc として出力されます。"
echo "[注意]"
echo "- このスクリプトは 1 ブロックぶんのデータのみ暗号化できます。"
echo
exit 1
fi
getRandStr() {
openssl rand -hex 16 2>&1
}
catURL() {
if type curl 1>/dev/null 2>/dev/null; then
curl --fail -s "$1"
elif type wget 1>/dev/null 2>/dev/null; then
wget -nv -O - "$1"
elif type fetch 1>/dev/null 2>/dev/null; then
fetch -q -o - "$1"
else
echo >&2 'データ取得に必要なコマンド(curl/wget/fetch)がインストールされていません。'
exit 1
fi
}
# コマンド引数取得
# ----------------
USERNAME="$1"
INPUTFILE="$2"
if [ ! -r "$INPUTFILE" ]; then
echo >&2 "暗号化したいファイル ${INPUTFILE} が見つかりません。"
exit 1
fi
# 出力ファイル名設定
# ------------------
OUTPUTFILE="$2.enc"
if [ $# -eq 3 ]; then
OUTPUTFILE=$3
fi
# trap の設定
# -----------
# スクリプト終了後一時ファイルを削除します。
# - 参考URL : https://qiita.com/m-yamashita/items/889c116b92dc0bf4ea7d
trap 'rm -rf /tmp/${USERNAME}.*' 0
# 一時ファイル
# ------------
if ! RAND="$(getRandStr)"; then
echo >&2 'OpenSSL によるランダム値の取得に失敗しました。'
echo >&2 "エラー内容: ${RAND}"
exit 1
fi
PATHPUBKEY="/tmp/${USERNAME}.${RAND}.pub"
# RSA 公開鍵の取得
# ----------------
# ユーザの GitHub の公開鍵一覧の1行目を取得
# - 取得先は: https://github.com/<user name>.keys
# - 参考URL : https://qiita.com/m0r1/items/af16c41475d493ab6774
printf "%s" "${USERNAME} の GitHub 上の公開鍵を取得中 ... "
list_keys="$(catURL "https://github.com/${USERNAME}.keys")" || {
echo >&2 "NG:公開鍵を取得できませんでした。"
exit 1
}
if [ -z "$list_keys" ]; then
echo >&2 "NG:公開鍵が存在しませんでした"
exit 1
fi
echo "$list_keys" | head -n 1 >"$PATHPUBKEY" || {
echo >&2 "NG:公開鍵を保存できませんでした。"
exit 1
}
echo "OK"
# 公開鍵のアクセス権変更
# ------------------
printf "%s" "取得した公開鍵のアクセス権を変更中 (0644 -> 0600) ... "
if ! chmod 0600 "$PATHPUBKEY"; then
echo >&2 "NG:ファイルのアクセス権を変更できませんでした。"
exit 1
fi
echo "OK"
# 公開鍵のフォーマット変換
# ------------------------
# - 参考URL :
# - https://qiita.com/drobune/items/bf5d689eff7f69ed6866
# - https://qiita.com/connvoi_tyou/items/3e86b6b68c3f398b3244
printf "%s" "RSA 形式の公開鍵を PKCS8 形式に変換中 ... "
if ! ssh-keygen -f "$PATHPUBKEY" -e -m pkcs8 >"${PATHPUBKEY}.pkcs8"; then
echo >&2 "NG:RSA -> PKCS8 変換中にエラーが発生しました。"
exit 1
fi
echo "OK"
# テキストの暗号化
# ----------------
# このスクリプトは 1 ブロックで可能なデータ量のみ暗号化します。そのため長いテキ
# ストは暗号化できません。
# - 参考URL : https://qiita.com/kunichiko/items/3c0b1a2915e9dacbd4c1
# - RSA鍵のビット長 = 最大暗号化可能バイト数
# 768 = 85
# 1024 = 117
# 2048 = 246
# 4096 = 502
# 8192 = 1018
printf "%s" "公開鍵でファイルを暗号化中 ... "
if ! openssl rsautl \
-encrypt \
-pubin \
-inkey "${PATHPUBKEY}.pkcs8" \
-in "$INPUTFILE" \
-out "$OUTPUTFILE"; then
echo >&2 "NG:暗号化に失敗しました。ファイルのサイズなど、エラー内容を確認ください。"
exit 1
fi
echo "OK"
# 一時ファイルの削除
# ------------------
printf "%s" "一時ファイルの削除中 ... "
if ! (rm "$PATHPUBKEY" && rm "${PATHPUBKEY}.pkcs8"); then
echo >&2 "NG:一時ファイルの削除に失敗しました。 '/tmp/' ディレクトリ内を手動で削除してください。"
exit 1
fi
echo "OK"
# 終了表示
# --------
echo
echo "暗号化を完了しました。このファイルを相手に送ってください。"
echo "暗号化済みファイル: ${OUTPUTFILE}"
echo
exit 0