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
이와 같은 스크립트를 생성하여 여러 파일을 해시한 다음 해당 해시의 연결을 해시할 수 있습니다. 모든 데이터를 먼저 연결하는 대신 이와 같은 두 부분으로 구성된 해시는 난독화를 방지해야 합니다. 연결하면 입력 간의 경계에 대한 정보가 손실되기 때문입니다(예: 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"
두 파일의 예:
$ 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