Como você usa a biblioteca cripta em C para a criptografia DES? (setkey, criptografado, cripta, etc.)

StackOverflow https://stackoverflow.com/questions/1418846

  •  07-07-2019
  •  | 
  •  

Pergunta

Preciso fazer alguma criptografia de DES simples em C para interagir com algum código antigo. Pelo que eu entendo, você pode usar a biblioteca "cripta" para isso, com as funções setkey, criptografando, cripta etc. Eu tenho mexido com ela e não consigo acertar. Falta o exemplo na página do homem para setkey/criptografia.

Quero obter a mesma saída que seria capaz de obter com algum código Java (veja abaixo).

Então, digamos que eu tenho duas matrizes de personagens em C.

char *message = "hellothe";
char *key = "iamakey0";

Alguém pode dar um exemplo de como criptografá -los com o setkey/criptografar e obter o mesmo resultado que eu faria com o código Java? Sei que você precisa colocar mensagem e chave em uma matriz de 64 bytes, onde cada char representa um pouco, mas parte disso também é confusa. Aparentemente, você tem que acertar a paridade nisso ou algo assim?

public static byte[] encryptDES(byte[] message, byte[] key) {
    byte[] encrypted = new byte[0];
    try{
        Cipher c = Cipher.getInstance("DES");
        c.init(Cipher.ENCRYPT_MODE,new SecretKeySpec(key,"DES"));
        encrypted = c.doFinal(message);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return encrypted;
}
Foi útil?

Solução

Porque você está ligando Cipher.getInstance Com apenas a corda "DES", você não está especificando um modo cifra ou método de preenchimento. Isso significa que você obtém os padrões, o que depende do que o provedor de criptografia Java que você está usando - você precisa saber exatamente o que eles devem escrever C. compatíveis (você realmente deve especificá -los em vez de confiar nos padrões).

Se você estiver usando o provedor SUNJCE, os padrões para o DES são o Modo BCE e o PKCS #5 preenchimento. A melhor maneira de fazer isso provavelmente é usar o OpenSSL ou outra biblioteca de criptografia carnuda - mas se você quiser usar funções que geralmente são encontradas na biblioteca C padrão em plataformas do tipo Unix, o ecb_crypt Família de funções será muito mais fácil de trabalhar do que o setkey / encrypt família.

Você precisará adicionar o PKCS#5 preenchido ao criptografar e verificar (e descartá -lo) ao descriptografar). A seguir ecb_pkcs5_encrypt A função deve fazer o equivalente aproximado do código Java acima usando essas funções.

/* Returns a newly-allocated buffer containing the contents of `data',
 * padded out to a multiple of 8 bytes using PKCS #5 style padding.
 *
 * If `padded_len` is non-NULL, the value it points to is updated to
 * the size of the padded output data.
 *
 * Returns NULL on error.
 */
char *pad_pkcs5(const char *data, size_t data_len, size_t *padded_len)
{
    char *padded_data;
    unsigned padding_len = 8 - (data_len % 8);
    const char padding = padding_len;
    char *pad_ptr;

    /* check for length overflow */
    if (data_len + padding_len < data_len)
        return NULL;

    /* Copy data into a new buffer and pad it out */
    padded_data = malloc(data_len + padding_len);

    if (!padded_data)
        return NULL;

    memcpy(padded_data, data, data_len);

    if (*padded_len)
    {
        *padded_len = data_len + padding_len;
    }

    /* Add the padding bytes */
    pad_ptr = padded_data + data_len;
    while (padding_len--)
    {
        *pad_ptr++ = padding;
    }

    return padded_data;
}

/* Returns a newly-allocated buffer containing the contents of `data',
 * encrypted with `key' using DES/ECB/PKCS5.
 *
 * If `out_len` is non-NULL, the value it points to is updated to
 * the size of the encrypted output data (which will always be a
 * multiple of 8).
 *
 * Returns NULL on error.
 */
char *ecb_pkcs5_encrypt(const char *key, const char *data, size_t data_len, size_t *out_len)
{
    char des_key[8];
    char *padded_data;
    size_t padded_len;
    int status;

    /* One of the few cases where strncpy() is exactly what we want! */
    strncpy(des_key, key, sizeof des_key);
    des_setparity(des_key);

    padded_data = pad_pkcs5(data, data_len, &padded_len);

    if (!padded_data)
        return NULL;

    status = ecb_crypt(des_key, padded_data, padded_len, DES_ENCRYPT);

    if (DES_FAILED(status))
        return NULL;

    if (out_len)
        *out_len = padded_len;

    return padded_data;
}

Outras dicas

Não use Crypt (). Ele usa algum algoritmo não padrão, por isso será muito difícil interoperar com outros sistemas. Além disso, o DES não é seguro de qualquer maneira.

Sugiro que você use o OpenSSL em C. A maioria de suas cifras é compatível com o JCE.

Se você realmente tem que usar o Crypt, o Sun's Jre vem com uma aula para lidar com cripta,

   com.sun.security.auth.module.Crypt

Esta é a classe interna, então a documentação não está lá. Basta ler o código -fonte.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top