Bashの複数のソースからハッシュを生成したいと思います。
私は次のことができることを知っています。
echo -n "STRING" | sha256sum
または
sha256sum [FILE]
私に必要なのは:
STRING + FILE
FILE + FILE
STRING + STRING
STRING + FILE + STRING
例えばSTRING + FILE
のハッシュ値を
STRING
変数に保存し、 のハッシュ値を[FILE]
変数に保存します。合計のハッシュを計算して生成します。ハッシュを
STRING
ファイルに保存し、ハッシュを[FILE]
同じファイルに保存し、そのファイルのハッシュを作成します。
単一のコマンドを使用してハッシュを生成できますか?
たとえば、echo "STRING" + [FILE] | sha256sum
どうすればいいですか、推奨または正しい方法は何ですか?
修正する
Romeo Ninovの回答に基づいて例1:
echo -n "STRING" && cat [FILE] | sha256sum
私がするとき:
例2:
echo $(echo -n "STRING" | sha256sum) $(sha256sum [FILE]) | sha256sum
何を使うべきですか?私は別の結果を得ます。これを達成する正しい方法は何ですか?
答え1
このようなスクリプトを生成して複数のファイルをハッシュし、そのハッシュの接続をハッシュできます。すべてのデータを最初にリンクするのではなく、これらの2つの部分で構成されるハッシュは難読化を防ぐ必要があります。接続すると、入力間の境界に関する情報が失われます(例:ab
+ c
!= a
+ bc
)。
#!/bin/bash
# function to get the hashes
H() {
sha256sum "$@" |
LC_ALL=C sed '
s/[[:blank:]].*//; # retain only the hash
s/^\\//; # remove a leading \ that GNU sha256sum at least
# inserts for file names where it escapes some
# characters (such as CR, LF or backslash).'
}
# workaround for command substitution removing final newlines
hashes=$(H "$@"; echo .)
hashes=${hashes%.}
# just for clarity
printf "%s\n" "----"
printf "%s" "$hashes"
printf "%s\n" "----"
# hash the hashes
final=$(printf "%s" "$hashes" | H)
echo "final hash of $# files: $final"
2つのファイルの例:
$ echo hello > hello.txt
$ echo world > world.txt
$ bash hash.sh hello.txt world.txt
----
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
e258d248fda94c63753607f7c4494ee0fcbe92f1a76bfdac795c9d84101eb317
----
final hash of 2 files: 27201be8016b0793d29d23cb0b1f3dd0c92783eaf5aa7174322c95ebe23f9fe8
プロセス置換を使用して、同じ出力を提供する文字列を挿入することもできます。
$ bash hash.sh hello.txt <(echo world)
[...]
final hash of 2 files: 27201be8016b0793d29d23cb0b1f3dd0c92783eaf5aa7174322c95ebe23f9fe8
同じ入力データ(hello\nworld\n
)に異なる区切り文字を指定すると、ハッシュ値が異なります。
$ bash hash.sh <(printf h) <(printf "ello\nworld\n")
[...]
final hash of 2 files: 0453f1e6ba45c89bf085b77f3ebb862a4dbfa5c91932eb077f9a554a2327eb8f
もちろん、入力ファイルの順序を変更すると、ハッシュ値も変更されます。
出力のダッシュ間の部分は単に明確にするためのものであり、sha256sum
実際の使用のためにはそれらを削除する必要があります。
sed
上記では、のハッシュ文字列を使用しましたsha256sum
。その部分を削除すると、| sed ...
ファイル名が含まれます。hash.sh hello.txt world.txt
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 hello.txt
e258d248fda94c63753607f7c4494ee0fcbe92f1a76bfdac795c9d84101eb317 world.txt
サブハッシュは同じですが、最終的なハッシュへの入力が異なり、提供された結果もf27b5175dec88c76dc6a7b368167cd18875da266216506e10c503a56befd7e14
異なります。明らかにファイル名を変更すると(からを含むhello.txt
)、./hello.txt
ハッシュ値が変更されます。また、プロセス置換を使用すると、実装に応じて奇妙なファイル名が表示されるため(/dev/fd/63
LinuxのBashと同様に)、ここではあまり役に立ちません。
上記の入力の最終ハッシュは次のとおりです。16進符号化それぞれ改行文字で終わる入力要素のハッシュです。私はいません。考えるそれ以上の分離が必要であり、ハッシュの長さが固定されているため、技術的に改行文字を削除することもできます(ただし改行文字は無料で提供されるため、人間が読みやすくなります)。
sha256sum
ただし、これは単純なハッシュ値のみを提供することに注意してください。認証タグを生成するツールを探している場合は、HMACなどを見て長さ拡張攻撃(直接的な攻撃は脆弱である可能性がH(key + data)
ある)などに注意する必要があります。
答え2
すべての情報とコメントを受け取った後、考えられる解決策は次のとおりです。
- 各ソースを別々にハッシュします。
- 事前に個別にハッシュされていない限り、ソースを接続しないでください。
- ソースをハッシュするときに区切り記号またはソルトの使用を検討してください。
- たとえば、ブロックを持つ元帳でさらに処理および保存するための最良のアプローチは、現在のほとんどのプライベートおよびパブリックブロックチェーンがどのように機能するかに似たハッシュツリー(Merkleハッシュツリー)を使用することです。
例:
同じハッシュ結果:
HASH_OF((abc) + (def))
HASH_OF((ab) + (cdef))
HASH_OF((abcde) + (f))
他のハッシュ結果:
HASH_OF( (HASH_OF(abc)) + (HASH_OF(def)) )
HASH_OF( (HASH_OF(ab)) + (HASH_OF(cdef)) )
HASH_OF( (HASH_OF(abcde)) + (HASH_OF(f)) )
区切り記号/ソルトと組み合わせた現在のアプローチは次のとおりです。
HASH_OF( (HASH_OF(abcde + [delimters/salt])) + (HASH_OF(f + [delimters/salt])) )
引き続き、この例を私の特定の要件に合わせて拡張します。
スクリプトで実装する方が便利で明確になります。
echo $(echo -n "STRING1" | sha256sum)$(echo -n "STRING2" | sha256sum) | sha256sum