Python hashlib.md5 和 ejabberd

2 投票
4 回答
2022 浏览
提问于 2025-04-16 12:14

我在使用一个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 个回答

0

hashlib这个库用起来很简单,不需要特别的设置。你说的“挂掉”是什么意思呢?是在哪个地方挂掉了?你可以用pdb.set_trace()这个工具来逐步查看代码的执行过程,或者使用'strace'或'ltrace'来检查程序调用的API。

1

我查看了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,这样程序根本不会进入主循环。

1

我也一直在纠结同样的问题。对于_openssl和_hashlib之间的绑定问题,我实在找不到原因。不管是什么问题,我都得修改Python的源代码,这样做其实不太现实。所以我最后选择使用了一个pycrypto的包装,这样在这个情况下加密功能就不会被阻塞了。

pip install pycrypto
from Crypto.Hash import MD5
m = MD5.new()
m.update("%s%s" % (salt ,clear))
h.hexdigest()

撰写回答