XOR de uma variável shell e um arquivo binário

XOR de uma variável shell e um arquivo binário

Eu tenho uma senha armazenada em uma variável shell (que foi lida na entrada da linha de comando).

Eu também tenho um arquivo-chave armazenado em um arquivo (que foi criado usando dde /dev/urandom).

Como quero exigir que ambos descriptografem meu disco rígido, gostaria de fazer um XOR, armazená-lo em um arquivo e usá-lo como chave.

Gostaria, portanto, de saber qual seria a maneira mais simples de fazer isso.

xxdseria um ajuste perfeito se permitisse -be -pao mesmo tempo, mas aparentemente não...


Editar: vou usá-lo emhttps://github.com/xavierm02/combine-keys

Responder1

Seu shell pode lidar com operações bit a bit, porém, para qualquer processamento sério, serámuitolento e não consegue lidar com nada além de cerca de 20 dígitos por vez. Ainda:

sh <<\CMD 
    printf 'printf "%%b" "\\0$((%04o^04))"'  "'a" |\
    . /dev/stdin
CMD

#OUTPUT
A

Eu usei bcno passado para capturar bytes em binário, então sua pergunta me levou a pesquisar no Google ...

Exclusivo ou (XOR) para GNU bc

Se você encontrou essa pergunta na Internet, é provável que esteja procurando o equivalente de bc ao ^operador de C.

Fato perturbador: tal coisa não existe em bc. Em bc, o operador de seta para cima é usado para exponenciação de inteiros, ou seja, 2^xretorna uma potência de 2 e não x com o bit 2 invertido. Se você está procurando equivalentes aos operadores bit a bit para XOR, bem como AND, OR e mais alguns parentes exóticos, verifique o logic.bc deste site e seus parentes que contêm funções para executar cada um deles.

Se você está procurando uma lógica XORpara colocar em uma instrução if, como lógico &&e ||, tente usar !=e colocar suas condições entre colchetes. por exemplo:

c=0;if((a==1)!=(b==2)){c=3}

Definirá c como 3, se a for 1 ou b for 2, mas não se a for 1 e b for 2 ao mesmo tempo

(Era uma vez, esse era o segredo dos componentes internos da função logic.bc xor(), mas foi substituído por um algoritmo mais rápido.)

O acima é do bcFAQ. A logic.bcfunção mencionada acima inclui a bitwiselógica que você está procurando. Pode ser encontradoaqui. Sua descrição:

Um grande conjunto de funções para executarbit a bitfunções como AND, OR, NOT e XOR. Usa complemento de dois para números negativos, ao contrário das versões anteriores deste arquivo, que não tinham suporte algum. Algumas das funções aqui usarão a variável global de largura de bits, que é inicializada como parte deste arquivo, para emular tamanhos de bytes/palavras encontrados na maioria dos computadores. Se esta variável for definida como zero, uma largura de bits infinita será assumida. Muitas funções exibirão um aviso se houver suspeita de que uma representação secundária de ponto flutuante de um número foi gerada, por exemplo:

1.1111... is an SFPR of10,0000...;`

Esses avisos podem ser desabilitados definindo a variável global sfpr_warncomo 0 (o padrão é 1).

  • Tamanho fixo da palavra
  • Tamanho infinito de palavras
  • Bit a bit comum
  • Complemento de dois
  • Mudança de bits
  • Código cinza
  • 'Multiplicação'
  • Ponto flutuante
  • Ponto flutuante 'Multiplicação'
  • Código cinza + ponto flutuante

Responder2

Eu usei um binário C.

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "No argument given.\n");
        exit(1);
    }
    char *filename = argv[1];

    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        fprintf(stderr, "Could not open given file.");
        exit(1);
    }
    int c1;
    int c2;
    do {
        c1 = fgetc(stdin);
        c2 = fgetc(file);
        if (c1 == EOF) {
            while (c2 != EOF) {
                printf("%c", c2);
                c2 = fgetc(file);
            }
            break;
        } else  if (c2 == EOF) {
            while (c1 != EOF) {
                printf("%c", c1);
                c1 = fgetc(stdin);
            }
            break;
        }
        int c = c1 ^ c2;
        printf("%c", c);
    } while (true);

    exit(0);
}

Responder3

Eu tenho algo quase funcionando no SH, mas é muito lento

#!/bin/sh

small_hex_to_bin() {
    hex=$1
    hex_length=${#1}
    bin=$(echo "ibase=16;obase=2;$hex" | bc)
    bin_length=$((4*$hex_length))
    bin=$(printf %0*d $bin_length $bin)
    echo $bin
}

hex_to_bin() {
    hex=$1
    hex_length=${#hex}
    for i in $(seq 1 $hex_length); do
        hex_digit=$(expr substr $hex $i 1)
        bin_digits=$(small_hex_to_bin $hex_digit)
        echo -n $bin_digits
    done
    echo ""
}

bin_to_hex() {
    bin=$1
    hex=$(echo "ibase=2;obase=10000;$bin" | bc)
    echo $hex
}

char_to_hex() {
    char=$1
    hex_lower=$(printf %x \'$char\')
    hex=$(echo $hex_lower | tr '[:lower:]' '[:upper:]')
    echo $hex
}

char_to_bin() {
    char=$1
    hex=$(char_to_hex $char)
    bin=$(small_hex_to_bin $hex)
    echo $bin
}

string_to_bin() {
    s=$1
    l=${#s}
    for i in $(seq 1 $l); do
        char=$(expr substr $s $i 1)
        bin=$(char_to_bin $char)
        echo -n $bin
    done
    echo ""
}

file_to_bin() {
    filename=$1
    hex_spaces=$(xxd -u -p $filename)
    hex=$(echo $hex_spaces | tr -d '\n' | tr -d ' ')
    bin=$(hex_to_bin $hex)
    echo $bin
}

min() {
    if [ $1 -ge $2 ]; then
        echo $2
    else
        echo $1
    fi
}

bit_xor() {
    if [ $1 -eq $2 ]; then
        echo 0
    else
        echo 1
    fi
}

xor() {
    b1=$1
    b2=$2
    l1=${#b1}
    l2=${#b2}
    l=$(min $l1 $l2)
    for i in $(seq 1 $l); do
        c1=$(expr substr $b1 $i 1)
        c2=$(expr substr $b2 $i 1)
        c=$(bit_xor $c1 $c2)
        echo -n $c
    done
    next_i=$(($l + 1))
    if [ $l -ne $l1 ]; then
        for i in $(seq $next_i $l1); do
            c1=$(expr substr $b1 $i 1)
            echo -n $c1
        done
    fi
    if [ $l -ne $l2 ]; then
        for i in $(seq $next_i $l2); do
            c2=$(expr substr $b2 $i 1)
            echo -n $c2
        done
    fi
    echo ""
}

#stdin=$(cat)
#file=$(cat $1)
#hex_to_bin $1
file_to_bin $1

informação relacionada