计算哈希并将其添加到 python 中的文件
Calculate and add hash to a file in python
一种检查文件是否已被修改的方法是计算并存储文件的哈希值(或校验和)。然后在任何时候都可以重新计算哈希值并将其与存储的值进行比较。
我想知道是否有办法将文件的哈希值存储在文件本身中?我在考虑文本文件。
计算散列的算法应该是迭代的,并且考虑将散列添加到正在为其计算散列的文件中...有意义吗?有空吗?
谢谢!
编辑:
https://security.stackexchange.com/questions/3851/can-a-file-contain-its-md5sum-inside-it
好吧,虽然它看起来像一个奇怪的想法,但它可能是 windows NTFS 文件系统的 属性 的一个应用程序:File Streams.
它允许在不更改默认流内容的情况下将许多 流 添加到文件中。例如:
echo foo > foo.text
echo bar > foo.text:alt
type foo.text
=> foo
more < foo.text:alt
=> bar
但是列出目录时,您只能看到一个文件:foo.txt
所以在你的用例中,你可以在名为 hash
的流中写入主流的哈希值,然后将 hash
流的内容与主流的哈希值进行比较。
请注意:由于我不知道的原因,type foo.text:alt
生成以下错误:
"The filename, directory name, or volume label syntax is incorrect."
这就是为什么我的示例按照 MSDNUsing streams page 中的建议使用 more <
所以假设你有一个 myhash
函数来给出文件的哈希值(你可以使用 hashlib
模块轻松构建一个):
def myhash(filename):
# compute the hash of the file
...
return hash_string
你可以这样做:
def store_hash(filename):
hash_string = myhash(filename)
with open(filename + ":hash") as fd:
fd.write(hash_string)
def compare_hash(filename):
hash_string = myhash(filename)
with open(filename + ":hash") as fd:
orig = fd.read()
return (hash_string == orig)
from Crypto.Hash import HMAC
secret_key = "Don't tell anyone"
h = HMAC.new(secret_key)
text = "whatever you want in the file"
## or: text = open("your_file_without_hash_yet").read()
h.update(text)
with open("file_with_hash") as fh:
fh.write(text)
fh.write(h.hexdigest())
现在,正如某些人试图指出的那样,尽管他们看起来很困惑 - 您需要记住该文件的末尾有散列,并且散列本身不是散列的一部分。所以当你想 检查 文件时,你会按照以下行做一些事情:
end_len = len(h.hex_digest())
all_text = open("file_with_hash").read()
text, expected_hmac = all_text[:end_len], all_text[end_len:]
h = HMAC.new(secret_key)
h.update(text)
if h.hexdigest() != expected_hmac:
raise "Somebody messed with your file!"
应该清楚的是,仅此 并不能确保您的文件未被更改;典型的用例是加密您的文件,但采用明文的哈希值。这样,如果有人更改了哈希值(在文件末尾)或尝试更改消息中的任何字符(加密部分),事情就会不匹配,你就会知道发生了什么变化。
恶意行为者将无法更改文件并修复哈希以匹配,因为他们需要更改一些数据,然后使用您的私钥重新哈希所有内容 .只要没有人知道您的私钥,他们就不知道如何重新创建正确的哈希值。
这是一个有趣的问题。如果您采用适当的约定来散列和验证文件的完整性,就可以做到这一点。假设你有这个文件,即 main.py
:
#!/usr/bin/env python
# encoding: utf-8
print "hello world"
现在,您可以将 SHA-1 散列作为注释附加到 python 文件:
(printf '#'; cat main.py | sha1sum) >> main.py
已更新main.py
:
#!/usr/bin/env python
# encoding: utf-8
print "hello world"
#30e3b19d4815ff5b5eca3a754d438dceab9e8814 -
因此,要验证文件是否被修改,您可以在 Bash:
中执行此操作
if [ "$(printf '#';head -n-1 main.py | sha1sum)" == "$(tail -n1 main.py)" ]
then
echo "Unmodified"
else
echo "Modified"
fi
当然,有人可能会通过手动更改哈希字符串来欺骗您。为了阻止这些坏人,您可以通过在将哈希添加到最后一行之前使用 秘密字符串 调整文件来改进系统。
改进版
在最后一行添加哈希值,包括您的秘密字符串:
(printf '#';cat main.py;echo 'MyUltraSecretTemperString12345') | sha1sum >> main.py
检查文件是否被修改:
if [ "$(printf '#';(head -n-1 main.py; echo 'MyUltraSecretTemperString12345') | sha1sum)" == "$(tail -n1 main.py)" ]
then
echo "Unmodified"
else
echo "Modified"
fi
使用这个改进的版本,坏人只有先找到你的超级密钥才能愚弄你。
的粗略实现
一种检查文件是否已被修改的方法是计算并存储文件的哈希值(或校验和)。然后在任何时候都可以重新计算哈希值并将其与存储的值进行比较。
我想知道是否有办法将文件的哈希值存储在文件本身中?我在考虑文本文件。
计算散列的算法应该是迭代的,并且考虑将散列添加到正在为其计算散列的文件中...有意义吗?有空吗?
谢谢!
编辑: https://security.stackexchange.com/questions/3851/can-a-file-contain-its-md5sum-inside-it
好吧,虽然它看起来像一个奇怪的想法,但它可能是 windows NTFS 文件系统的 属性 的一个应用程序:File Streams.
它允许在不更改默认流内容的情况下将许多 流 添加到文件中。例如:
echo foo > foo.text
echo bar > foo.text:alt
type foo.text
=> foo
more < foo.text:alt
=> bar
但是列出目录时,您只能看到一个文件:foo.txt
所以在你的用例中,你可以在名为 hash
的流中写入主流的哈希值,然后将 hash
流的内容与主流的哈希值进行比较。
请注意:由于我不知道的原因,type foo.text:alt
生成以下错误:
"The filename, directory name, or volume label syntax is incorrect."
这就是为什么我的示例按照 MSDNUsing streams page 中的建议使用 more <
所以假设你有一个 myhash
函数来给出文件的哈希值(你可以使用 hashlib
模块轻松构建一个):
def myhash(filename):
# compute the hash of the file
...
return hash_string
你可以这样做:
def store_hash(filename):
hash_string = myhash(filename)
with open(filename + ":hash") as fd:
fd.write(hash_string)
def compare_hash(filename):
hash_string = myhash(filename)
with open(filename + ":hash") as fd:
orig = fd.read()
return (hash_string == orig)
from Crypto.Hash import HMAC
secret_key = "Don't tell anyone"
h = HMAC.new(secret_key)
text = "whatever you want in the file"
## or: text = open("your_file_without_hash_yet").read()
h.update(text)
with open("file_with_hash") as fh:
fh.write(text)
fh.write(h.hexdigest())
现在,正如某些人试图指出的那样,尽管他们看起来很困惑 - 您需要记住该文件的末尾有散列,并且散列本身不是散列的一部分。所以当你想 检查 文件时,你会按照以下行做一些事情:
end_len = len(h.hex_digest())
all_text = open("file_with_hash").read()
text, expected_hmac = all_text[:end_len], all_text[end_len:]
h = HMAC.new(secret_key)
h.update(text)
if h.hexdigest() != expected_hmac:
raise "Somebody messed with your file!"
应该清楚的是,仅此 并不能确保您的文件未被更改;典型的用例是加密您的文件,但采用明文的哈希值。这样,如果有人更改了哈希值(在文件末尾)或尝试更改消息中的任何字符(加密部分),事情就会不匹配,你就会知道发生了什么变化。
恶意行为者将无法更改文件并修复哈希以匹配,因为他们需要更改一些数据,然后使用您的私钥重新哈希所有内容 .只要没有人知道您的私钥,他们就不知道如何重新创建正确的哈希值。
这是一个有趣的问题。如果您采用适当的约定来散列和验证文件的完整性,就可以做到这一点。假设你有这个文件,即 main.py
:
#!/usr/bin/env python
# encoding: utf-8
print "hello world"
现在,您可以将 SHA-1 散列作为注释附加到 python 文件:
(printf '#'; cat main.py | sha1sum) >> main.py
已更新main.py
:
#!/usr/bin/env python
# encoding: utf-8
print "hello world"
#30e3b19d4815ff5b5eca3a754d438dceab9e8814 -
因此,要验证文件是否被修改,您可以在 Bash:
中执行此操作if [ "$(printf '#';head -n-1 main.py | sha1sum)" == "$(tail -n1 main.py)" ]
then
echo "Unmodified"
else
echo "Modified"
fi
当然,有人可能会通过手动更改哈希字符串来欺骗您。为了阻止这些坏人,您可以通过在将哈希添加到最后一行之前使用 秘密字符串 调整文件来改进系统。
改进版
在最后一行添加哈希值,包括您的秘密字符串:
(printf '#';cat main.py;echo 'MyUltraSecretTemperString12345') | sha1sum >> main.py
检查文件是否被修改:
if [ "$(printf '#';(head -n-1 main.py; echo 'MyUltraSecretTemperString12345') | sha1sum)" == "$(tail -n1 main.py)" ]
then
echo "Unmodified"
else
echo "Modified"
fi
使用这个改进的版本,坏人只有先找到你的超级密钥才能愚弄你。
的粗略实现