Base64 и нестандартный - PullRequest
       47

Base64 и нестандартный

1 голос
/ 03 февраля 2011

Я пытаюсь создать Python-клиент для Bacula, но у меня есть проблемы с аутентификацией.

Алгоритм:


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?

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 ]

1 голос
/ 04 февраля 2011

Для проверки вашей реализации CRAM-MD5 лучше всего использовать несколько простых тестовых векторов и проверять комбинации входов (вызов, пароль, имя пользователя) с ожидаемым результатом.

Вот один пример (из * 1003)*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

Тем не менее, я определенно нашел в сети примеры, где ответ, сгенерированный вышеуказанным кодом, отличается от ожидаемого ответа, указанного на соответствующем сайте, поэтому мне все еще не совсем ясно, какк тому, что происходит в этих случаях.

0 голосов
/ 16 сентября 2017

Я взломал это.

Я столкнулся с той же самой проблемой, с которой вы столкнулись, и только что потратил около 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 лет с тех пор, как вы спросили, но, возможно, кто-то найдет это полезным.

...