2011-02-03 106 views
1

我尝试为bacula创建一个python客户端,但我遇到了一些认证问题。Base64和非标准

的算法是:


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'

有一种方法比临港基地64的Bacula的公司实行更简单吗?

int 
bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible) 
{ 
    uint32_t reg, save, mask; 
    int rem, i; 
    int j = 0; 

    reg = 0; 
    rem = 0; 
    buflen--;      /* allow for storing EOS */ 
    for (i=0; i >= (rem - 6); 
     if (j
+2

您的标题和帖子似乎都被切断了。 – 2011-02-03 13:53:24

回答

1

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

这里有一个例子(从http://blog.susam.in/2009/02/auth-cram-md5.html):

import hmac 
username = '[email protected]' 
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 

这就是说,我当然发现的例子上,其中由上面的代码生成的响应从相关网站上注明的预期响应不同的网络,所以我还不完全清楚在这些情况下发生了什么。

0

我已经破解了这个。

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

问题是Bacula的base64被破坏,错误!

有两个问题是:

首先是作为签约,而不是无符号的输入字节处理。这样做的效果是,如果一个字节的最高位设置(> 127),那么它将被视为负数;当它与前一个字节的“剩余”位相结合时,全部设置为(二进制1)。

第二个是,在b64处理完所有完整的6位输出块之后,可能还有0,2或4位(取决于输入块模数3)。处理这个问题的标准Base64方法是将剩余的位相乘,因此它们是最后6位块中的最高位,并对它们进行处理 - Bacula将它们保留为最低位。请注意,Bacula的某些版本可能接受“Bacula破解base64编码”和标准版本,用于传入认证;他们似乎使用破碎的身份验证。

def bacula_broken_base64(binarystring): 
    b64_chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/" 
    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年了,但也许别人会觉得这很有用。