Base64和非标准

2024-04-29 07:38:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图为bacula创建一个python客户机,但是在身份验证方面有一些问题。在

算法是:


import hmac
import base64
import re

...

challenge = re.search("auth cram-md5 ()", data)
#exemple ''
passwd = 'b489c90f3ee5b3ca86365e1bae27186e'
hm = hmac.new(passwd, challenge).digest()
rep = base64.b64encode(hm).strp().rstrip('=')
#result with python : 9zKE3VzYQ1oIDTpBuMMowQ
#result with bacula client : 9z+E3V/YQ1oIDTpBu8MowB'

有比端口bacula实现base64更简单的方法吗?在

^{pr2}$

Tags: importre算法auth身份验证search客户机with
2条回答

为了验证您的CRAM-MD5实现,最好使用一些简单的测试向量,并对照预期输出检查(challenge、password、username)输入的组合。在

下面是一个例子(来自http://blog.susam.in/2009/02/auth-cram-md5.html):

import hmac
username = 'foo@susam.in'
passwd = 'drowssap'
encoded_challenge = 'PDc0NTYuMTIzMzU5ODUzM0BzZGNsaW51eDIucmRzaW5kaWEuY29tPg=='
challenge = encoded_challenge.decode('base64')
digest = hmac.new(passwd, challenge).hexdigest()
response = username + ' ' + digest
encoded_response = response.encode('base64')
print encoded_response
# Zm9vQHN1c2FtLmluIDY2N2U5ZmE0NDcwZGZmM2RhOWQ2MjFmZTQwNjc2NzIy

也就是说,我确实在网上找到了一些例子,上面的代码生成的响应与相关站点上的预期响应不同,所以我仍然不完全清楚这些情况下发生了什么。在

我已经破解了这个。在

我遇到了与您完全相同的问题,并且刚刚花了4个小时来确定问题并重新实现它。在

问题是Bacula的base64坏了,错了!在

它有两个问题:

首先,传入字节被视为有符号的,而不是无符号的。这样做的效果是,如果一个字节具有最高的位集(大于127),那么它将被视为负数;当它与前一个字节中的“剩余”位组合在一起时,所有位都被设置为(二进制1)。在

第二个是,在b64处理完所有的6位输出块之后,可能还剩下0、2或4位(取决于输入块模数3)。处理这个问题的标准Base64方法是将剩余的位相乘,因此它们是最后6位块中的最高位,并对其进行处理-Bacula将其保留为最低位。在

注意,Bacula的某些版本可能同时接受“Bacula breaked base64编码”和标准编码,以进行传入身份验证;它们似乎使用损坏的base64编码进行身份验证。在

def bacula_broken_base64(binarystring):
    b64_chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    remaining_bit_count=0
    remaining_bits=0
    output=""
    for inputbyte in binarystring:
        inputbyte=ord(inputbyte)
        if inputbyte>127:
            # REPRODUCING A BUG! set all the "remaining bits" to 1.
            remaining_bits=(1 << remaining_bit_count) - 1
        remaining_bits=(remaining_bits<<8)+inputbyte
        remaining_bit_count+=8
        while remaining_bit_count>=6:
            # clean up:
            remaining_bit_count-=6
            new64=(remaining_bits>>remaining_bit_count) & 63 # 6 highest bits
            output+=b64_chars[new64]
            remaining_bits&=(1 << remaining_bit_count) - 1
    if remaining_bit_count>0:
        output+=b64_chars[remaining_bits]

    return output

我知道你已经6年没问了,但也许别人会觉得这个有用。在

相关问题 更多 >