여러 소스 또는 입력을 사용하여 Bash에서 해시 또는 sha256sum을 만드는 방법은 무엇입니까? 권장되는 접근 방식은 무엇입니까?

여러 소스 또는 입력을 사용하여 Bash에서 해시 또는 sha256sum을 만드는 방법은 무엇입니까? 권장되는 접근 방식은 무엇입니까?

Bash의 여러 소스에서 해시를 생성하고 싶습니다.

나는 다음을 할 수 있다는 것을 알고 있습니다.

echo -n "STRING" | sha256sum

또는

sha256sum [FILE]

나에게 필요한 것은:

  1. STRING + FILE
  2. FILE + FILE
  3. STRING + STRING
  4. STRING + FILE + STRING

예를 들어STRING + FILE

  1. 의 해시 값을 STRING변수에 저장하고 의 해시 값을 [FILE]변수에 저장합니다. 합계의 해시를 계산하고 생성합니다.

  2. 해시를 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/63Linux의 Bash와 마찬가지로) 여기에서는 덜 유용합니다.


위에서 입력의 최종 해시는 다음과 같습니다.16진수 인코딩각각 개행 문자로 끝나는 입력 요소의 해시입니다. 나는 아니에요생각하다그보다 더 많은 분리가 필요하며 해시의 길이가 고정되어 있기 때문에 기술적으로 개행 문자를 제거할 수도 있습니다(그러나 개행 문자는 무료로 제공되므로 사람이 더 쉽게 읽을 수 있습니다).

sha256sum하지만 이는 단순한 해시 값만 제공한다는 점에 유의하세요 . 인증 태그를 생성하는 도구를 찾고 있다면 HMAC 등을 살펴보고 길이 확장 공격(직접적인 공격은 H(key + data)취약할 수 있음) 등에 주의해야 합니다.

사용 사례에 따라 고려할 수 있습니다.안전또는크립토SE, 아니면 실제 전문가를 고용하세요.

답변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

관련 정보