Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Twofish

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
19.01.2008, 12:45 Uhr
~tobb0
Gast


Hi,

mein Programm muss zu bestimmten Zwecken Dateien verschlüsseln (und zwar mit Twofish).
Dazu brauche ich aber eine fertige Bibliothek, die das macht, weil ich als Krypto-Laie mir nicht zutraue, Twofish exakt zu implementieren.
Jemand meinte nun ich solle dafür dringend GnuPG nehmen, aber wie kann ich das in mein Programm integrieren?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
19.01.2008, 13:42 Uhr
0xdeadbeef
Gott
(Operator)


Ich würd gcrypt vorschlagen, denn dazu hab ich grad ein Programm zur Hand, das ich mal geschrieben hab

C++:
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <gcrypt.h>

#include <sys/mman.h>
#include <termios.h>
#include <unistd.h>

#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif

#ifndef PASS_MAX
#define PASS_MAX 256
#endif

#define BLOCKSIZE 512
#define KEYSIZE   32

static char const salt[] = "fia92\01m dwq+=**";
static size_t     salt_size = sizeof(salt);

typedef gcry_error_t (*transform_func_t)(gcry_cipher_hd_t,
                                         void       *, size_t,
                                         void const *, size_t);

gcry_error_t diagnose_gcry_error(gcry_error_t err, char const *file, int line) {
  if(err != 0) {
    fprintf(stderr, "%s, %d: %s\n", file, line, gcry_strerror(err));
  }

  return err;
}

#define CHECK_GCRY(err) diagnose_gcry_error(err, __FILE__, __LINE__)

static char *get_password(char *buf, size_t n) {
  struct termios old, new;
  char *ret;

  if(tcgetattr(STDIN_FILENO, &old) != 0)
    return NULL;

  new = old;
  new.c_lflag &= ~ECHO;

  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &new) != 0)
    return NULL;

  ret = fgets(buf, n, stdin);

  (void) tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);

  putchar('\n');

  return ret;
}

static void progress_cb(void       UNUSED *cb_data,
                        char const UNUSED *what,
                        int                printchar,
                        int                current,
                        int                total)
{
  printf("\r[%3.2g]%c", (double) current / total * 100, printchar);
  fflush (stdout);
}

int dencrypt(FILE *in,
             FILE *out,
             gcry_cipher_hd_t cipher,
             transform_func_t crypto_func) {
  gcry_error_t err = 0;
  int          ret = 0;
  size_t chars_read;
  char inbuf[BLOCKSIZE], outbuf[BLOCKSIZE];

  mlock( inbuf, BLOCKSIZE);
  mlock(outbuf, BLOCKSIZE);

  while((chars_read = fread(inbuf, sizeof(char), BLOCKSIZE, in)) > 0) {
    err = CHECK_GCRY(crypto_func(cipher,
                                 outbuf, chars_read,
                                 inbuf , chars_read));
    if(err ||
       fwrite(outbuf, sizeof(char), chars_read, out) != chars_read) {
      ret = -1;
    }
  }

  memset(outbuf, 0, BLOCKSIZE);
  memset( inbuf, 0, BLOCKSIZE);

  munlock( inbuf, BLOCKSIZE);
  munlock(outbuf, BLOCKSIZE);

  return ret;
}

int main(int argc, char *argv[]) {
  gcry_md_hd_t     hash;
  gcry_cipher_hd_t cipher;
  char             pass[PASS_MAX];
  FILE            *in,
                  *out;

  if(argc != 4 || !strchr("de", argv[1][0])) {
    return -1;
  }

  mlock(pass, PASS_MAX);

  printf("Initialisiere gcrypt %s\n", gcry_check_version(NULL));
  CHECK_GCRY(gcry_control(GCRYCTL_INIT_SECMEM, 8192));
  gcry_set_progress_handler(progress_cb, NULL);

  CHECK_GCRY(gcry_cipher_open(&cipher,
                              GCRY_CIPHER_AES256,
                              GCRY_CIPHER_MODE_CFB,
                              GCRY_CIPHER_SECURE));
  CHECK_GCRY(gcry_md_open(&hash, GCRY_MD_SHA256, 0));

  printf("Schlüssel: ");
  fflush(stdout);

  if(get_password(pass, PASS_MAX) != NULL) {
    gcry_md_write(hash, pass, strlen(pass));
    CHECK_GCRY(gcry_md_final(hash));

    CHECK_GCRY(gcry_cipher_setkey(cipher,
                                  gcry_md_read(hash, GCRY_MD_SHA256),
                                  KEYSIZE));
    CHECK_GCRY(gcry_cipher_setiv (cipher, salt, salt_size));

    in  = fopen(argv[2], "r");
    out = fopen(argv[3], "w");

    if(in  != NULL &&
       out != NULL) {
      if(dencrypt(in,
                  out,
                  cipher,
                  argv[1][0] == 'e' ?
                    gcry_cipher_encrypt :
                    gcry_cipher_decrypt)
         != 0) {
        fputs("De-/Encryption failed.", stderr);
      }
    }

    if(out != NULL) fclose(out);
    if(in  != NULL) fclose(in );
  }

  gcry_md_close(hash);
  gcry_cipher_close(cipher);

  CHECK_GCRY(gcry_control(GCRYCTL_TERM_SECMEM));

  memset(  pass, 0, PASS_MAX);

  munlock(pass, PASS_MAX);

  return 0;
}


...du müsstest halt nur statt GCRY_CIPHER_AES256 GCRY_CIPHER_TWOFISH benutzen.

Genauere Doku dazu hier. Die Bibliothek ist sehr einfach zu benutzen, aber ein bisschen Hintergrundwissen über Kryptographie muss man natürlich trotzdem haben.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 19.01.2008 um 14:23 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
20.01.2008, 15:33 Uhr
~tobb0
Gast


Hi 0xdeadbeef,

vielen Dank für das Programm.
Ich bin es mal durchgegangen und bin jetzt einige Schritte weiter, weil ich ansatzweise kapiere, wie Verschlüsselungen von Dateien funktionieren...
Jetzt habe ich noch ein paar Fragen:

1. Wozu benutzt du mlock und was macht es genau? (Es verhindert memory swapping glaube ich... nur wozu?)

2. Auch aus der Doku bin ich nicht schlau geworden, was du mit

Code:
gcry_control(GCRYCTL_INIT_SECMEM, 8192)

bewirkst?

3. Als Schlüssel benutzt du einen Hashwert des "Schlüsselworts", weil dieser immer gleich lang ist und der Schlüssel für den jeweiligen Algorithmus immer eine bestimmte Länge haben muss. Habe ich das soweit richtig verstanden?
Warum aber ist dann KEYSIZE = 32 Bytes aber du verwendest AES256 (256Bit = 64 Bytes)?

4. Die Funktion get_password scheint mir sehr kompliziert zu sein.
Ich programmiere mit wxWidgets und werde einfach einen kleinen Dialog mit einem TextControl, dass nur Sternchen als Zeichen anzeigt, verwenden, um an das Passwort des Users zu gelangen.
Oder baue ich damit Sicherheitslücken ein?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
20.01.2008, 20:15 Uhr
0xdeadbeef
Gott
(Operator)


1. mlock verhindert, dass der angegebene Speicherbereich geswappt wird, das ist richtig. In den betroffenen Speicherbereich schreibe ich das Passwort, und das soll nachher keinesfalls irgendwo auf der Festplatte landen.

2. Das initialisiert sicheren Speicher für gcrypt, der nachher von der Cipher genutzt wird, die mit GCRY_CIPHER_SECURE initialisiert wurde; der Grund ist der selbe wie bei 1.

3. 64 * 8 = 512

4. Die get_password-Funktion ist nicht besonders kompliziert; sie stellt nur das Terminal so um, dass die Eingabe nicht ausgegeben wird, liest eine Zeile ein und stellt den alten Status wieder her. Was die Sicherheitslücke angeht, naja, wenn du der Textcontrol beibringen kannst, den Speicherbereich zu mlocken, und wenn du den betroffenen Speicherbereich nullen kannst, sobald du das Passwort nicht mehr brauchst, dann wohl nicht. Aber hat wxWidgets nicht ein Passwortwidget für sowas?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: