Pythonでhash値を求める
最近Linuxのアプリケーションのハッキングのニュースを見た。Webフレームワークのダウンロードモジュールが悪意のある書き換えをされて置き換えられたらしい。
このモジュールは最近更新されていないもので、GitHubにあるソースコードに変更がないのに、モジュールが更新されており気づいたようだ。今回はダウンロードサイトに記述されているhash値と比較していたら入れ替えに気づいたとのこと。できる限りソフトウェアーのダウンロードの際にはhash値の確認をするようにと言う記事だった。正直言うと僕もhash値でダウンロードしたソフトウェアーを確認するという習慣はない。これからはそれではいけないと言うことで、ハッシュで比較していくことを心がけたい。
しかし、
どうやるの???
ってことだし、hashを求めるソフトが改残されていたら・・・。と妙に心配性になってしまった。
ならばPythonで作ってみようということで、hash値を求めたり比較したりするコマンドを作ってみた。GUIは(今のところ)。これからダウンロードしたファイルはこれでチェックしていきたい。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Python hash check
#
# cre. 2022.06.02 dai.
import sys
import argparse
import hashlib
def m_argparse(modes: list):
# 引数定義とパース
# input: list of hash mode
parser = argparse.ArgumentParser(description="check hash value")
parser.add_argument('-f', '--file', default='<gui>',
help='file to made hash')
parser.add_argument('--hash', help='hash value')
parser.add_argument('-a', '--all', action='store_true',
help='make all possiblity value')
parser.add_argument('-m', '--mode', default='sha256', choices=modes,
help='hash mode')
parser.add_argument('-l', '--list', help='list hash mode',
action='store_true')
args = parser.parse_args()
return(args.file, args.mode, args.hash, args.list, args.all)
def mc_hash(fmodes: dict, filename: str, mode: str, vhash: str,
f_all: bool) -> int:
ret = -1
try:
# ファイル を バイナリーモード で開く
with open(filename, 'rb') as f:
# ファイルを読み取る
fileData = f.read()
# ファイルのハッシュ値の計算
if vhash is not None:
# 引数に渡したhash値と比較
if fmodes[mode](fileData).hexdigest() == vhash:
print(f'same hash values {vhash}')
ret = 0
else:
print(f'unmatch hash value {vhash}')
ret = -1
else:
if f_all:
# すべてのhash値を出力
for key, func in fmodes.items():
print(f'{key} : {fmodes[key](fileData).hexdigest()}')
ret = 1
else:
# 引数に指定されたhash値を出力
print(f'{mode} : {fmodes[mode](fileData).hexdigest()}')
ret = 1
return(ret)
except Exception as err:
print(type(err))
print(err)
return(-1)
def main() -> int:
# Hash名とhashlibのハッシュ関数を辞書に登録
fmodes = {'md5': hashlib.md5,
'sha1': hashlib.sha1,
'sha224': hashlib.sha224,
'sha256': hashlib.sha256,
'sha384': hashlib.sha384,
'sha512': hashlib.sha512,
'sha3_224': hashlib.sha3_224,
'sha3_256': hashlib.sha3_256,
'sha3_384': hashlib.sha3_384,
'sha3_512': hashlib.sha3_512,
'blake2b': hashlib.blake2b,
'blake2s': hashlib.blake2s}
modes = list(fmodes.keys())
# 引数定義とパース
(filename, mode, vhash, f_list, f_all) = m_argparse(modes)
# 扱えるhashの一覧を表示
if f_list:
print(f'mode\n{modes}')
return(1)
# hash計算メイン
if filename != '<gui>':
return(mc_hash(fmodes, filename, mode, vhash, f_all))
else:
print('I am sorry that gui version is not implemented yet.')
return(-1)
if __name__ == "__main__":
ret = main()
if ret < 0:
print(f'error : {ret}')
sys.exit(ret)
補足
引数処理はあとで構造化する
GUI版は気が向いたら作る
ーーーーーーーーーーーーーーーーーー
自己責任でソースコードの2次利用は可能。
本プログラムで問題を起こしても責任は負いません。