1

我尝试为 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 的 base 64 实现更简单的方法吗?

整数
bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
{
   uint32_t reg,保存,掩码;
   对数,我;
   整数 j = 0;

   注册 = 0;
   rem = 0;
   布芬——;/* 允许存储 EOS */
   对于 (i=0; i >= (rem - 6);
      如果 (j
4

2 回答 2

1

要验证您的 CRAM-MD5 实现,最好使用一些简单的测试向量并根据预期输出检查(挑战、密码、用户名)输入的组合。

这是一个示例(来自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

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

于 2011-02-04T06:41:20.250 回答
1

我已经破解了这个。

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

问题是 Bacula 的 base64 坏了,而且是错误的!

它有两个问题:

首先是传入的字节被视为有符号,而不是无符号。这样做的效果是,如果一个字节设置了最高位(>127),则将其视为负数;当它与来自先前字节的“剩余”位组合时,都设置为(二进制 1)。

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

请注意,某些版本的 Bacula 可能同时接受“Bacula 损坏的 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 年了,但也许其他人会觉得这很有用。

于 2017-09-16T02:17:49.587 回答