Python hashlib.md5 和 ejabberd
我在使用一个Python脚本作为ejabberd 2.1.6的外部认证选项。
我想开始加密在认证验证中传输的明文密码,这样它们就不会以明文形式存储在后端数据库里。当我把以下代码添加到我的Python脚本中并重启ejabberd时,它就卡住了:
import hashlib
clear = "barfoo"
salt = "foobar"
hash = hashlib.md5( salt + clear ).hexdigest()
hashlib需要特定的权限才能运行吗?
当我以普通用户(ejabberd)身份运行时,它没有问题。但是当这个Python脚本在ejabberd的外部认证中运行时,它就卡住了。
我尝试让它把“哈希值”写入一个文件,但从来没有成功……如果我以“ejabberd”用户身份运行,它就能正常写入文件。
我试图找到关于在ubuntu上使用这个库的限制信息,但没有成功。有什么想法吗?
-sd
** 2011年2月22日:这是从 https://git.process-one.net/ejabberd/mainline/blobs/raw/2.1.x/doc/dev.html#htoc8 改编的完整脚本:
#!/usr/bin/python
import sys
from struct import *
import hashlib
def from_ejabberd():
input_length = sys.stdin.read(2)
(size,) = unpack('>h', input_length)
return sys.stdin.read(size).split(':')
def to_ejabberd(bool):
answer = 0
if bool:
answer = 1
token = pack('>hh', 2, answer)
sys.stdout.write(token)
sys.stdout.flush()
def auth(username, server, password):
clear = "barfoo"
salt = "foobar"
hash = hashlib.md5( salt + clear ).hexdigest()
if (password == hash): return True
else: return False
def isuser(username, server):
return True
def setpass(username, server, password):
return True
while True:
data = from_ejabberd()
success = False
if data[0] == "auth":
success = auth(data[1], data[2], data[3])
elif data[0] == "isuser":
success = isuser(data[1], data[2])
elif data[0] == "setpass":
success = setpass(data[1], data[2], data[3])
to_ejabberd(success)
4 个回答
hashlib这个库用起来很简单,不需要特别的设置。你说的“挂掉”是什么意思呢?是在哪个地方挂掉了?你可以用pdb.set_trace()这个工具来逐步查看代码的执行过程,或者使用'strace'或'ltrace'来检查程序调用的API。
我查看了hashlib的源代码,虽然看起来不需要太多东西,但它确实会导入一些.so文件作为模块,其中一个会调用openssl。整体看起来是比较安全的,但如果ejabberd试图防止调用第三方代码(或者你有SELinux之类的东西在运行),那么事情可能会变得有点奇怪。我在REPL中得到了这个:
>>> import _md5
>>> _md5.__file__
'/usr/lib/python2.7/lib-dynload/_md5module.so'
你可以在你的机器上试试这个,然后试着放入
_md5 = imp.load_dynamic('_md5', '/usr/lib/python2.7/lib-dynload/_md5module.so')
或者直接
import _md5
(记得把路径更新成你自己的)在出问题的代码行之前,并在后面加上一些追踪语句。用_hashlib替代_md5也试试(hashlib默认使用_hashlib,它会包装openssl,但如果加载失败或者没有需要的哈希,它会退回到_md5、_sha等)。如果不是导入出问题,那么你可以尝试调用_md5.new(salt + clear)和_hashlib.openssl_md5(salt + clear),看看是不是其中之一。
如果是导入的问题,可能在这里解决过类似的问题。我对ejabberd不太了解,所以无法将他们的解决方案与你的问题联系起来,真是抱歉。
不过我必须说,在我知道的所有Python实现中,条件语句中用=代替==会引发SyntaxError,这样程序根本不会进入主循环。
我也一直在纠结同样的问题。对于_openssl和_hashlib之间的绑定问题,我实在找不到原因。不管是什么问题,我都得修改Python的源代码,这样做其实不太现实。所以我最后选择使用了一个pycrypto的包装,这样在这个情况下加密功能就不会被阻塞了。
pip install pycrypto
from Crypto.Hash import MD5 m = MD5.new() m.update("%s%s" % (salt ,clear)) h.hexdigest()