Wie verwenden Sie die Krypta -Bibliothek in C für die Verschlüsselung? (SetKey, Verschlüsseln, Krypta usw.)

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

  •  07-07-2019
  •  | 
  •  

Frage

Ich muss eine einfache DES -Verschlüsselung in C durchführen, um mit einem alten Code zu interfasieren. Soweit ich weiß, können Sie die "Krypta" -Bibliothek dafür verwenden, mit den Funktionen SetKey, Verschlüsseln, Krypta usw. Ich habe damit herumgespielt und kann es nicht richtig machen. Das Beispiel auf der Mannseite für SetKey/Encrypt fehlt.

Ich möchte die gleiche Ausgabe wie ich mit einem Java -Code erhalten können (siehe unten).

Nehmen wir also an, ich habe zwei Charakter -Arrays in C.

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

Kann jemand ein Beispiel dafür geben, wie man diese mit SetKey/Verschlüsselung verschlüsselt und das gleiche Ergebnis wie ich aus dem Java -Code erzielt? Mir ist klar, dass Sie Nachrichten und Schlüssel in ein 64-Byte-Array einfügen müssen, in dem jedes Zeichen ein wenig darstellt, aber einige davon sind auch verwirrend. Anscheinend musst du auch die Bit -Parität richtig machen oder so?

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;
}
War es hilfreich?

Lösung

Weil du anrufst Cipher.getInstance mit nur der Zeichenfolge "DES", Sie geben keine Verschlüsselungsmodus oder eine Polstermethode an. Dies bedeutet, dass Sie die Standardeinstellungen erhalten, was davon abhängt, welchen Java -Kryptographieanbieter Sie verwenden - Sie müssen genau wissen, was sie sind, um kompatibel C zu schreiben. (Sie sollten sie wirklich angeben, anstatt sich auf Standardeinstellungen zu verlassen).

Wenn Sie den SunJCE -Anbieter verwenden, sind die Standardeinstellungen für DES ECB -Modus und PKCS #5 Polsterung. Der beste Weg, dies zu tun, besteht wahrscheinlich darin, OpenSSL oder eine andere fleischige Krypto -Bibliothek zu verwenden. Wenn Sie jedoch Funktionen verwenden möchten, die normalerweise in der Standard -C -Bibliothek auf UNIX -Typ -Plattformen enthalten sind, ist die ecb_crypt Die Familie der Funktionen wird viel einfacher zu arbeiten als mit der setkey / encrypt Familie.

Sie müssen beim Verschlingen PKCS#5 -Padding hinzufügen und beim Entschlüsseln überprüfen (und verwerfen). Folgende ecb_pkcs5_encrypt Die Funktion sollte das grobe Äquivalent des obigen Java -Codes mit diesen Funktionen ausführen.

/* 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;
}

Andere Tipps

Verwenden Sie nicht Crypt (). Es verwendet einen nicht standardmäßigen Algorithmus, so dass es sehr schwierig ist, mit anderen Systemen zusammenzuarbeiten. Außerdem ist Des sowieso nicht sicher.

Ich schlage vor, Sie verwenden OpenSSL in C. Die meisten seiner Chiffren sind mit JCE kompatibel.

Wenn Sie wirklich Krypta verwenden müssen, kommt Jre von Sun mit einer Klasse, um mit Krypta umzugehen.

   com.sun.security.auth.module.Crypt

Dies ist eine interne Klasse, daher ist die Dokumentation nicht vorhanden. Lesen Sie einfach den Quellcode.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top