XOR um arquivo contra uma chave

3

Como é possível, de ferramentas de linha de comando bash ou linux padrão, para XOR um arquivo em uma chave? Algo como:

cat my1GBfile | xor my1MB.key > my1GBfile.encrypted
Off-topic: Eu sei que a criptografia é bastante fraca com este exemplo, mas eu estava apenas imaginando se isso está disponível nas ferramentas de linha de comando bash ou linux padrão (ou ainda melhor: do bash e cygwin, porque eu uso ambos Linux e Windows).

    
por Basj 16.10.2017 / 21:07

2 respostas

2

bash não pode lidar com caracteres ASCII NUL , então você não estará fazendo isso com as funções shell, você precisa de um pequeno programa para ele. Isso pode ser feito em praticamente qualquer idioma, mas parece mais fácil fazê-lo em C, talvez assim:

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

int
main(int argc, char *argv[])
{
    FILE *kf;
    size_t ks, n, i;
    long pos;
    unsigned char *key, *buf;

    if (argc != 2) {
        fprintf (stderr, "Usage: %s <key>\a\n", argv[0]);
        exit(1);
    }
    if ((kf = fopen(argv[1], "rb")) == NULL) {
        perror("fopen");
        exit(1);
    }

    if (fseek(kf, 0L, SEEK_END)) {
        perror("fseek");
        exit(1);
    }
    if ((pos = ftell(kf)) < 0) {
        perror("ftell");
        exit(1);
    }
    ks = (size_t) pos;
    if (fseek(kf, 0L, SEEK_SET)) {
        perror("fseek");
        exit(1);
    }
    if ((key = (unsigned char *) malloc(ks)) == NULL) {
        fputs("out of memory", stderr);
        exit(1);
    }
    if ((buf = (unsigned char *) malloc(ks)) == NULL) {
        fputs("out of memory", stderr);
        exit(1);
    }

    if (fread(key, 1, ks, kf) != ks) {
        perror("fread");
        exit(1);
    }

    if (fclose(kf)) {
        perror("fclose");
        exit(1);
    }

    freopen(NULL, "rb", stdin);
    freopen(NULL, "wb", stdout);

    while ((n = fread(buf, 1, ks, stdin)) != 0L) {
        for (i = 0; i < n; i++)
            buf[i] ^= key[i];
        if (fwrite(buf, 1, n, stdout) != n) {
            perror("fwrite");
            exit(1);
        }
    }

    free(buf);
    free(key);

    exit(0);
}

(isso requer mais algumas verificações de erros, mas tudo bem).

Compile o acima com:

cc -o xor xor.c

execute-o assim:

./xor my1MB.key <my1GBfile >my1GBfile.encrypted
    
por 16.10.2017 / 23:02
1

Com as ferramentas do GNU, você pode fazer:

paste <(od -An -vtu1 -w1 file) <(while :; do od -An -vtu1 -w1 key; done) |
  awk 'NF!=2{exit}; {printf "%c", xor($1, $2)}'

Você precisa de um shell (como o shell GNU) com suporte para substituição de processos, um od com suporte para a opção -w (como o GNU od ) e o GNU awk para xor() (e capacidade de produzir o byte NUL que nem todos fazem awk s).

    
por 17.10.2017 / 09:22