注册 登录
自由的生活_软路由 返回首页

心想事成的个人空间 https://bbs.routerclub.com/?681 [收藏] [复制] [分享] [RSS]

日志

DES, Blowfish, IDEA, MD5: implemtentation ( for Ondaquadra E-zine )

已有 177 次阅读2010-3-11 22:21 |

This article appeared on OndaQuadra0B Elettronic Magazine - Mar 2004 ]
OpenSSL/DES,OpenSSL/Blowfish,OpenSSL/IDEA,OpenSSL/MD5: implemtentation
UNISFED written and coded by Paolo Ardoino <paolo.ardoino@gmail.com>

0. Intro
1. Descrizione algoritmi
2. Funzioni & headers DES
3. Funzioni & headers Blowfish
4. Funzioni & headers IDEA
5. Funzioni & headers MD5

In questo articolo vedremo come implementare quattro tra gli algoritmi
piu' famosi e piu' usati nel campo della crittografia:
DES,Blowfish,IDEA,MD5

1. Descrizione algoritmi

DES[Data Encryption Standard]:
Il DES fu sviluppato dall'IBM nel 1970, divento' standard nel 1976
e fu adottato dal governo statunitense nel 1977 ed e' stato utilizzato
per lungo tempo dal governo e da aziende private.
Il DES e' un block cipher (cifrario a blocchi) che lavora con blocchi
di 64 bits (8 bytes), utilizzando chiavi a 56 bits.
Su ogni blocco vengono effettuate delle permutazioni oltre che 16
cicli di xor e permutazioni.
Nel 1998 e' stata dimostrata la vulnerabilita' di questo algoritmo,
da parte dell' EFF, utilizzando un attacco di tipo brute force.
Per ovviare a questo problema e' stato introdotto il 3DES, che e'
basato su una ripetizione del cifrario DES, utilizzando chiavi a 112
bits.

Blowfish:
Nel 1993 Bruce Schneier sviluupo l'algoritmo conosciuto come Blowfish.
Come il DES opera su blocchi di 64 bits. Blowfish puo' operare con
chiavi fino a 448 bits, anche se tipicamente si utilizzano chiavi
a 128 bits. L'utilizzo di Blowfish presenta molti vantaggi a partire
dalla sua velocita' e compattezza fino ad arrivare alla sicurezza
infatti non si conoscono attacchi efficaci, inoltre e' un algoritmo
non patentato.

IDEA[International Data Encryption Algorithm]:
L'algoritmo IDEA lavora con chiavi a 16 bytes (128 bits), su blocchi
di 64 bits. E' basato su 8 cicli identici seguiti da una trasformazione
dell'output.

MD5[Message Digest 5]
MD5, creato nel 1991 da Ronald Rivest e' una funzione one-way hashing,
cioe' prende un messaggio e ne deriva una stringa di un 16 bytes
chiamata anche message digest.

2. Funzioni & headers DES
#include <openssl/des.h>

Poiche' la password e' 64 bits (anche se poi e' ridotta a 56 bits) e
operiamo su blocchi di 8 bytes, quindi dovremmo operare su blocchi di
64 bits. Quindi dichiariamo che sia la password che i messaggi in
chiaro (plaintext) che quelli cifrati (cipher text) dovranno essere
blocchi di 64 bits; per fare questo introduciamo il tipo des_cblock.
Il tipo dello scheduling della password e' des_key_schedule.

Ora possiamo passare alle funzioni:

/* des_read_pw_string(): scrive la string contenuta in prompt,
leva l'echo sulla stdin e legge la password in input. La password
viene inserita in buf ed e' al massimo lenght caratteri. Se verfify
e' posto a 1 chiede la riconferma della password. */
int des_read_pw_string(char *buf, int lenght, const char *prompt,
int verify);

/* des_string_to_key(): converte la stringa contenuta in str in una
chiave DES a 64 bits */
void des_string_to_key(const char *str, des_cblock *key);

/* des_set_key_checked(): controlla se la chiave passata e' dispari
e imposta loschedule della chiave */
int des_set_key_checked(const_des_cblock *key,
des_key_schedule schedule);

/* des_ecb_encrypt(): e' la routine di cifratura base per il DES
offerta dalla libreria. Cifra/Decifra blocchi di 8 bytes a seconda
che mode sia DES_ENCRYPT o DES_DECRYPT. ks e' il key schedule */
void des_ecb_encrypt(const_des_cblock *input, des_cblock *output,
des_key_schedule ks, int enc);

Per informazioni sulle funzioni non illustrate qui: man des

3. Funzioni & headers Blowfish

#include <openssl/bf.h>
Per leggere la password da input usiamo la stessa funzione che
utilizziamo per il DES: des_read_pw_string() [leggete la sez. 2].
La chiave dovra' essere di tipo BF_KEY.

/* BF_set_key(): imposta la chiave (di tipo BF_KEY) usando la stringa
data di lunghezza len */
void BF_set_key(BF_KEY *key, int len, const unsigned char *data);

/* BF_ecb_encrypt(): e' la funzione base per cifrare/decifrare
offerta dalla libreria. Cifra/Decifra blocchi di 8 bytes a seconda
che mode sia BF_ENCRYPT o BF_DECRYPT. */
void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
BF_KEY *key, int enc);

4. Funzioni & headers IDEA

#include <openssl/idea.h>

Lo schedule della chiave deve essere impostato a IDEA_KEY_SCHEDULE.
Ricordo, inoltre, che il ciphertext e il plaintext devono essere
blocchi di 8 bytes.
Per leggere la password da input usiamo la stessa funzione che
utilizziamo per il DES: des_read_pw_string() [leggete la sez. 2].

/* idea_set_encrypt_key(): imposta il key schedule della chiave
per la fase di cifrazione */
void idea_set_encrypt_key(const unsigned char *key,
IDEA_KEY_SCHEDULE *ks);

/* idea_set_decrypt_key(): imposta il key schedule della chiave
per la fase di decifrazione partendo dal key schedule generato
con idea_set_encrypt_key() */
void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek,
IDEA_KEY_SCHEDULE *dk);

/* idea_ecb_encrypt(): cifra/decifra [a seconda del key schedule
passatogli] i dati contenuti nel blocco di 8 bytes in e li mette
nel blocco di 8 bytes out. */
void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
IDEA_KEY_SCHEDULE *ks);

5. Funzioni & headers MD5

#include <openssl/md5.h>

Questa libreria include alcune funzioni per l'hashing dei messaggi.

/* MD5(): performa l'hash del messaggio passatogli */
unsigned char *MD5(const unsigned char *d, unsigned long n,
unsigned char *md);
[Se md e' NULL il message digest viene messo in un array statico]

A livello applicativo, invece di usare questa funzione conviene
utilizzare le routines EVP, che lavorano a piu' alto livello.

#include <openssl/evp.h>

/* EVP_md5(): ritorna una struttura EVP_MD per l'algoritmo md5 */
EVP_MD *EVP_md5(void);

/* EVP_DigestInit(): inizializza un context CTX per usare un digest
di tipo type*/
void EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);

/* EVP_DigestUpdate(): computa l'hash di cnt bytes di d nel CTX */
void EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d,
unsigned int cnt);

/* EVP_DigestFinal(): mette l'hash contenuto nel context CTX
in md*/
void EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,
unsigned int *s);

man md5

Ora che abbiamo visto le principali funzioni potete guardarvi
il codice sorgente di UNISFED.
[Il codice contiene anche l'algoritmo di crittografia a chiave pubblica
RSA, descritte nel numero 0A di Ondaquadra]

Da compilarsi [una volta suddivisi i files] in questo modo:
gcc unisfed.c -o unisfed -lssl

Ciao a tutti e alla prossima.
-------------------block_ciphers.c-------------------------------------
#include <openssl/des.h>
#include <openssl/blowfish.h>
#include <openssl/idea.h>
#define MAXPASSLEN 31

/* DES
 * If mode = 1 encrypts *filein file with DES algorithm
 * If mode = 0 decrypts *filein file with DES algorithm
 * output is written in *fileout file
 * Returns 1 if the function runs successfully
 * Works on 8 bytes blocks
 *
 */
void des_encrypt_decrypt(int mode, char *filein, char *fileout)
{
	FILE *fpin,*fpout;
	char buf[MAXPASSLEN];
	des_cblock key,inmsg,outmsg; /* key, plaintext, ciphertext must
	be 8 byte blocks */
	des_key_schedule sched;

	if (strcmp(filein,fileout) == 0) {
		fprintf(stderr,"Error: input and output files must not \
		be the same file.\n");
		exit(EXIT_FAILURE);
	}
	/* des_read_pw_string reads password from stdin and stores it
	in buf this function automatically asks to re-enter password
	and checks it */
	memset(buf,'\0',MAXPASSLEN);
	if (mode == 1) {
		printf("Encrypting file '%s' with des cipher.\n", \
		filein);
		if (des_read_pw_string(buf,MAXPASSLEN - 1,"Enter the \
		password:\n",1) != 0) {
			fprintf(stderr,"Error: failed to read \
			password.\n");
			exit(EXIT_FAILURE);
		}
	} else {
		printf("Decrypting file '%s' with des cipher.\n",\
		filein);
		if (des_read_pw_string(buf,MAXPASSLEN - 1,"Enter the \
		password:\n",0) != 0) {
			fprintf(stderr,"Error: failed to read \
			password.\n");
			exit(EXIT_FAILURE);
		}
	}
	/* des_string to key convers the password to a key */
	des_string_to_key(buf,&key);
	/* des_set_key_checked checks that a key passed in of odd
	parity and set up the key schedule */
	des_set_key_checked(&key,sched);
	fpin = fopen(filein,"r");
	if ((fpout = fopen(fileout,"w")) == NULL) {
		fprintf(stderr,"Error: failed to open output file.\n");
		exit(EXIT_FAILURE);
	}
	/* reads 8 bytes at a time(block=8bytes),encrypts/decrypts
	each block with ecb */
	while (fread(inmsg,1,8,fpin)) {
		memset(outmsg,'\0',8);
		des_ecb_encrypt(&inmsg,&outmsg,sched,mode);
		fwrite(outmsg,1,8,fpout);
		memset(inmsg,'\0',8);
	}
	fclose(fpin);
	fclose(fpout);
	printf("Done.\n");
	return;
}

/* Blowfish
 * If mode = 1 encrypts *filein file with Blowfish algorithm
 * If mode = 0 decrypts *filein file with Blowfish algorithm
 * output is written in *fileout file
 * Returns 1 if the function runs successfully
 * Works on 8 bytes blocks
 *
 */
void bf_encrypt_decrypt(int mode, char *filein, char *fileout)
{
	FILE *fpin,*fpout;
	char buf[MAXPASSLEN];
	unsigned char inmsg[8],outmsg[8]; /* blowfish operates on 8
	byte blocks */
	BF_KEY key;

	if (strcmp(filein,fileout) == 0) {
		fprintf(stderr,"Error: input and output files must \
		not be the same file.\n");
		exit(EXIT_FAILURE);
	}
	/* reads password from stdin using the same function used
	for des passwords */
	memset(buf,'\0',MAXPASSLEN);
	if (mode == 1) {
		printf("Encrypting file '%s' with BlowFish cipher.\n",\
		filein);
		if (des_read_pw_string(buf,MAXPASSLEN - 1,"Enter the \
		password:\n",1) != 0) {
			fprintf(stderr,"Error: failed to read \
			password.\n");
			exit(EXIT_FAILURE);
		}
	} else {
		printf("Decrypting file '%s' with BlowFish cipher.\n",\
		filein);
		if (des_read_pw_string(buf,MAXPASSLEN - 1,"Enter the \
		password:\n",0) != 0) {
			fprintf(stderr,"Error: failed to read \
			password.\n");
			exit(EXIT_FAILURE);
		}
	}
	/* set up the key using password stored in buf from
	des_read_pw_string */
	BF_set_key(&key,strlen(buf),buf);
	fpin = fopen(filein,"r");
	if ((fpout = fopen(fileout,"w")) == NULL) {
		fprintf(stderr,"Error: failed to open output file.\n");
		exit(EXIT_FAILURE);
	}
	/* reads 8 bytes at a time(block=8bytes),encrypts/decrypts each
	block with ecb */
	while (fread(inmsg,1,8,fpin)) {
		memset(outmsg,'\0',8);
		BF_ecb_encrypt(inmsg,outmsg,&key,mode);
		fwrite(outmsg,1,8,fpout);
		memset(inmsg,'\0',8);
	}
	fclose(fpin);
	fclose(fpout);
	printf("Done.\n");
	return;
}

/* IDEA
 * If mode = 1 encrypts *filein file with IDEA algorithm
 * If mode = 0 decrypts *filein file with IDEA algorithm
 * output is written in *fileout file
 * Returns 1 if the function runs successfully
 * Works on 8 bytes blocks
 *
 */
void idea_encrypt_decrypt(int mode, char *filein, char *fileout)
{
	FILE *fpin,*fpout;
	char buf[MAXPASSLEN];
	unsigned char inmsg[8],outmsg[8]; /* idea operates on 8
	byte blocks */
	IDEA_KEY_SCHEDULE sched,dc_sched;

	if (strcmp(filein,fileout) == 0) {
		fprintf(stderr,"Error: input and output files must not\
		be the same file.\n");
		exit(EXIT_FAILURE);
	}
	/* reads password from stdin using the same function used for
	des passwords */
	memset(buf,'\0',MAXPASSLEN);
	if (mode == 1) {
		printf("Encrypting file '%s' with IDEA cipher.\n",\
		filein);
		if (des_read_pw_string(buf,MAXPASSLEN - 1,"Enter the \
		password:\n",1) != 0) {
			fprintf(stderr,"Error: failed to read \
			password.\n");
			exit(EXIT_FAILURE);
		}
	} else {
		printf("Decrypting file '%s' with IDEA cipher.\n",\
		filein);
		if (des_read_pw_string(buf,MAXPASSLEN - 1,"Enter the \
		password:\n",0) != 0) {
			fprintf(stderr,"Error: failed to read \
			password.\n");
			exit(EXIT_FAILURE);
		}
	}
	/* set up the key schedule for encryption */
	idea_set_encrypt_key(buf,&sched);
	/* setting up the key schedule for decryption in mode == 0 */
	if (mode == 0) {
		idea_set_decrypt_key(&sched,&dc_sched);
		sched = dc_sched;
	}
	fpin = fopen(filein,"r");
	if ((fpout = fopen(fileout,"w")) == NULL) {
		fprintf(stderr,"Error: failed to open output file.\n");
		exit(EXIT_FAILURE);
	}
	/* reads 8 bytes at a time(block=8bytes),encrypts/decrypts each\
	block with ecb */
	while (fread(inmsg,1,8,fpin)) {
		memset(outmsg,'\0',8);
		idea_ecb_encrypt(inmsg,outmsg,&sched);
		fwrite(outmsg,1,8,fpout);
		memset(inmsg,'\0',8);
	}
	fclose(fpin);
	fclose(fpout);
	printf("Done.\n");
	return;
}
-------------------end block_ciphers.c---------------------------------

-------------------hash.c----------------------------------------------
#include <openssl/md5.h>
#include <openssl/evp.h>

void make_hex(u_char *in, u_char *out)
{
    const char    *hex = "0123456789abcdef";
    int i;

    for(i = 0; i < 16; i++, in++) {
        *out++ = hex[*in >> 4];
        *out++ = hex[*in & 0xf];
    }
    *out = 0x00;
    return;
}

/* MD5
 * Hashing algorithm
 * md5hash() performs the hash of a given file.
 */
void md5hash(char *filein)
{
	FILE *fp = NULL;
	unsigned int tmpsize=0,linesize=0;
	char *hashbuf = NULL;
	unsigned char *hash = NULL;
	EVP_MD_CTX ctx;

	printf("MD5 hash of '%s' file is:\n",filein);
	EVP_DigestInit(&ctx,EVP_md5()); /* initializes digest context*/
	fp = fopen(filein,"r");
	while ((linesize = getline(&hashbuf,&tmpsize,fp)) != -1) {
		EVP_DigestUpdate(&ctx,hashbuf,linesize); /* hashes
		linesize bytes of data at hashbuf */
		linesize = 0;
	}
	fclose(fp);
	hash = (unsigned char *)malloc(16);
	EVP_DigestFinal(&ctx,(unsigned char *)hash,NULL); /* retrieves
	the digest value */
	make_hex(hash, hashbuf);
	printf("%s\n",hashbuf);
	free(hashbuf);
	free(hash);
	return;
}

/* MD5
 * Hashing algorithm
 * md5cmp() compares the hash of two given files.
 */
void md5cmp(char *file1, char *file2)
{
	FILE *fp = NULL;
	unsigned int tmpsize=0,linesize=0;
	char *hashbuf = NULL;
	unsigned char *hash1 = NULL, *hash2 = NULL;
	EVP_MD_CTX ctx;

	printf("Comparing MD5 hashes of '%s' and '%s' files.\n",\
	file1,file2);
	EVP_DigestInit(&ctx,EVP_md5());
	fp = fopen(file1,"r");
	while ((linesize = getline(&hashbuf,&tmpsize,fp)) != -1) {
		EVP_DigestUpdate(&ctx,hashbuf,linesize);
		linesize = 0;
	}
	fclose(fp);
	hash1 = (unsigned char *)malloc(16);
	EVP_DigestFinal(&ctx,(unsigned char *)hash1,NULL);
	EVP_DigestInit(&ctx,EVP_md5()); /* initializes the digest
	context */
	linesize = 0;
	tmpsize = 0;
	fp = fopen(file2, "r");
	while ((linesize = getline(&hashbuf,&tmpsize,fp)) != -1) {
		EVP_DigestUpdate(&ctx,hashbuf,linesize); /* hashes
		linesize bytes of data at hashbuf */
		linesize = 0;
	}
	fclose(fp);
	hash2 = (unsigned char *)malloc(16);
	EVP_DigestFinal(&ctx,(unsigned char *)hash2,NULL); /* retrieves
	the digest value */
	if (strcmp(hash1,hash2) == 0)
	  printf("MD5 hashes match.\n");
	else
	  printf("MD5 hashes don't match.\n");
	free(hash1);
	free(hash2);
	free(hashbuf);
	return;
}
-------------------end hash.c------------------------------------------

-------------------misc.c----------------------------------------------
void help(char *name)
{
	printf("UniSFED [Simple File Encrypter/Decrypter] v%s\n",\
	VERSION);
	printf("Coded by Paolo Ardoino <paolo.ardoino@gmail.com>\n");
	printf("Usage:\n");
	printf("%s -h\t:displays this help\n",name);
	printf("%s -fh <file_to_hash>\t:performs the MD5 hash of \
	file_to_hash.\n",name);
	printf("%s -fc <file1_to_cmp> <file2_to_cmp>\t:compares the \
	MD5 hash of the two files.\n",name);
	printf("%s -e <-idea|-des|-bf|-rsa> <file_to_crypt> \
	<file_output> [rsa_pub.pem]]\t:encrypts file_to_crypt with \
	choosen cipher.\n",name);
	printf("%s -d <-idea|-des|-bf|-rsa> <file_to_decrypt> \
	<file_output> [rsa_sec.pem]\t:decrypts file_to_decrypt with choosen cipher.\n",name);
	printf("%s -grsa <numbits> <secfile> <pubfile>\t:generates a \
	RSA key pair.\n", name);
	printf("-idea: idea block cipher.\n");
	printf(" -des: des block cipher.\n");
	printf("  -bf: blowfish block cipher.\n");
	printf("Ex: %s -e -bf passwords.txt crypto_pass.txt\n",name);
	printf("Ex: %s -d -bf crypto_pass.txt pass_file.txt\n",name);
	printf("Ex: %s -fc file1 file2\n",name);
	printf("\nPlease report bugs to <ardoino.gnu@disi.unige.it>\n");
	return;
}

/*
 * fexists() checks for the existence of a given file.
 * return 0 if the file doesn't exist and 1 if it exists.
 */
int fexists(char *file)
{
	FILE *fp;
	if ((fp = fopen(file,"r")) == NULL) {
		return 0;
	} else {
		fclose(fp);
		return 1;
	}
}
-------------------end misc.c------------------------------------------

-------------------rsa.c-----------------------------------------------
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/rsa.h>

#define READPUB 0
#define READSEC 1

void rsa_ed(int mode, char *fin, char *fout, char *pemfile)
{
	int size=0,len=0,ks=0;
	RSA *key=NULL;
	FILE *fpin=NULL, *fpout=NULL;
	unsigned char *cipher=NULL,*plain=NULL;

	if (strcmp(fin, fout) == 0) {
		fprintf(stderr,"Error: input and output files must not\
		be the same file.\n");
		exit(EXIT_FAILURE);
	}
	if (mode == 0) {
		fpin = fopen(fin, "r");
		key = (RSA *)readpemkeys(READPUB, pemfile);
       		fpout = fopen(fout, "w");
		ks = RSA_size(key);
		plain = (unsigned char *)malloc(ks * \
		sizeof(unsigned char));
		cipher = (unsigned char*)malloc(ks * \
		sizeof(unsigned char));
		printf("Encrypting '%s' file.\n", fin);
		while(!feof(fpin)) {
			memset(plain,'\0',ks + 1);
			memset(cipher, '\0', ks + 1);
			len = fread(plain, 1, ks - 11, fpin);
			size = rsa_encrypt(key, plain, len, &cipher);
			fwrite(cipher, 1, size, fpout);
		}
		fclose(fpout);
		fclose(fpin);
		free(cipher);
		free(plain);
		RSA_free(key);
		printf("Done.\n");
	} else if (mode == 1) {
		fpin = fopen(fin, "r");
		key = (RSA *)readpemkeys(READSEC, pemfile);
		fpout = fopen(fout, "w");
		ks = RSA_size(key);
		cipher = (unsigned char*)malloc(ks * \
		sizeof(unsigned char));
		plain = (unsigned char*)malloc(ks * \
		sizeof(unsigned char));
		printf("Decrypting '%s' file.\n", fin);
		while(!feof(fpin)) {
			memset(cipher, '\0', ks);
			memset(plain, '\0', ks);
			if ((len = fread(cipher, 1, ks, fpin)) == 0)
 			break;
         		size = rsa_decrypt(key, cipher, len, &plain);
			fwrite(plain, 1, size, fpout);
       		}
		fclose(fpout);
		fclose(fpin);
		free(plain);
		free(cipher);
		RSA_free(key);
		printf("Done.\n");
	}
	return;
}

void genkey(int size, char *secfile, char *pubfile)
{
  RSA *key=NULL;
  FILE *fp;

  printf("Generating RSA keys[%d bits].\n", size);
  if (size < 64) {
    fprintf(stderr, "Error: RSA Key pair size too small.\n");
    fprintf(stderr, "size >= 64\n");
    exit(EXIT_FAILURE);
  }
  if((key = RSA_generate_key(size,3,NULL,NULL)) == NULL) {
    fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
    exit(EXIT_FAILURE);
  }
  if(RSA_check_key(key) < 1) {
    fprintf(stderr,"Error: Problems while generating RSA Key.\n \
    Retry.\n");
    exit(EXIT_FAILURE);
  }
  fp=fopen(secfile,"w");
  if(PEM_write_RSAPrivateKey(fp,key,NULL,NULL,0,0,NULL) == 0) {
    fprintf(stderr,"Error: problems while writing RSA Private \
    Key.\n");
    exit(EXIT_FAILURE);
  }
  fclose(fp);
  fp=fopen(pubfile,"w");
  if(PEM_write_RSAPublicKey(fp,key) == 0) {
    fprintf(stderr,"Error: problems while writing RSA Public Key.\n");
    exit(EXIT_FAILURE);
  }
  fclose(fp);
  RSA_free(key);
  printf("Done.\n");
  return;
}

void* readpemkeys(int type, char *pemfile)
{
  FILE *fp;
  RSA *key=NULL;

  if(type == READPUB) {
    if((fp = fopen(pemfile,"r")) == NULL) {
      fprintf(stderr,"Error: Public Key file doesn't exists.\n");
      exit(EXIT_FAILURE);
    }
    if((key = PEM_read_RSAPublicKey(fp,NULL,NULL,NULL)) == NULL) {
      fprintf(stderr,"Error: problems while reading Public Key.\n");
      exit(EXIT_FAILURE);
    }
    fclose(fp);
    return key;
  }
  if(type == READSEC) {
    if((fp = fopen(pemfile,"r")) == NULL) {
      fprintf(stderr,"Error: Private Key file doesn't exists.\n");
      exit(EXIT_FAILURE);
    }
    if((key = PEM_read_RSAPrivateKey(fp,NULL,NULL,NULL)) == NULL) {
      fprintf(stderr,"Error: problmes while reading Private Key.\n");
      exit(EXIT_FAILURE);
    }
    fclose(fp);
    if(RSA_check_key(key) == -1) {
      fprintf(stderr,"Error: Problems while reading RSA Private Key in \
      '%s' file.\n",pemfile);
      exit(EXIT_FAILURE);
    } else if(RSA_check_key(key) == 0) {
      fprintf(stderr,"Error: Bad RSA Private Key readed in '%s' \
      file.\n",pemfile);
      exit(EXIT_FAILURE);
    }
    else
      return key;
  }
  return key;
}

int rsa_encrypt(void *key, unsigned char *plain, int len, \
unsigned char **cipher)
{
  int clen=0;

  srand(time(NULL));
  if((clen = RSA_public_encrypt(len, plain, *cipher, (RSA*)key, \
  RSA_PKCS1_PADDING)) == -1) {
    fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
    exit(EXIT_FAILURE);
  } else
    return clen;
}

int rsa_decrypt(void *key, unsigned char *cipher, int len, \
unsigned char **plain)
{
  int plen=0;

  if((plen = RSA_private_decrypt(len, cipher, *plain, (RSA*)key, \
  RSA_PKCS1_PADDING)) == -1) {
    fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
    exit(EXIT_FAILURE);
  } else
    return plen;
}
-------------------end rsa.c-------------------------------------------

-------------------unisfed.c-------------------------------------------
#include "unisfed.h"

int main(int argc, char *argv[])
{
	if (argc == 1 || strcmp(argv[1],"-h") == 0 || \
	((strcmp(argv[1],"-e") != 0 && strcmp(argv[1],"-d") != 0 && \
	strcmp(argv[1],"-fh") != 0 && strcmp(argv[1],"-fc") != 0 && \
	strcmp(argv[1], "-grsa") != 0)))
		help(argv[0]);
	else if (strcmp(argv[1],"-d") == 0 && (argc == 5 || argc == 6) \
	&& (strcmp(argv[2],"-idea") == 0 ||strcmp(argv[2],"-des") == 0 \
	|| strcmp(argv[2],"-bf") == 0||strcmp(argv[2], "-rsa") == 0)){ \
		if (strcmp(argv[2],"-idea") == 0) {
			if (fexists(argv[3]) == 1)
				idea_encrypt_decrypt(0,argv[3],argv[4]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else if (strcmp(argv[2],"-des") == 0) {
			if (fexists(argv[3]) == 1)
				des_encrypt_decrypt(0,argv[3],argv[4]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else if (strcmp(argv[2],"-bf") == 0) {
			if (fexists(argv[3]) == 1)
				bf_encrypt_decrypt(0,argv[3],argv[4]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else if (strcmp(argv[2],"-rsa") == 0) {
			if (fexists(argv[3]) == 1)
				rsa_ed(1, argv[3], argv[4], argv[5]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else;
	} else if (strcmp(argv[1],"-e") == 0 && \
	(argc == 5 || argc == 6) && (strcmp(argv[2],"-idea") == 0 || \
	strcmp(argv[2],"-des") == 0 || strcmp(argv[2],"-bf") == 0 || \
	strcmp(argv[2], "-rsa") == 0)) {
		if (strcmp(argv[2],"-idea") == 0) {
			if (fexists(argv[3]) == 1)
				idea_encrypt_decrypt(1,argv[3], \
				argv[4]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else if (strcmp(argv[2],"-des") == 0) {
			if (fexists(argv[3]) == 1)
				des_encrypt_decrypt(1,argv[3],argv[4]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else if (strcmp(argv[2],"-bf") == 0) {
			if (fexists(argv[3]) == 1)
				bf_encrypt_decrypt(1,argv[3],argv[4]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else if (strcmp(argv[2],"-rsa") == 0) {
			if (fexists(argv[3]) == 1)
				rsa_ed(0, argv[3], argv[4], argv[5]);
			else fprintf(stderr,"Error: input file not \
			found.\n");
		} else;
	} else if (strcmp(argv[1],"-fh") == 0 && argc == 3) {
		if (fexists(argv[2]) == 1)
			md5hash(argv[2]);
		else fprintf(stderr,"Error: input file not found.\n");
	} else if (strcmp(argv[1],"-fc") == 0 && argc == 4) {
		if (fexists(argv[2]) == 1 && fexists(argv[3]) == 1)
			md5cmp(argv[2],argv[3]);
		else fprintf(stderr,"Error: input files not found.\n");
	} else if (strcmp(argv[1], "-grsa") == 0 && argc == 5)
		genkey(atoi(argv[2]), argv[3], argv[4]);
	else
		help(argv[0]);
	return 0;
}
-------------------end unisfed.c---------------------------------------

-------------------unisfed.h-------------------------------------------
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define VERSION "0.1"

/* Miscellaneous functions */
int fexists(char *file);
void help(char *name);

/* RSA fucntions */
void* readpemkeys(int type, char *pemfile); /*RSA*/
void genkey(int size, char *secfile, char *pubfile);/*RSA*/
int rsa_encrypt(void *key, unsigned char *plain, int len, \
unsigned char **cipher);/*RSA*/
int rsa_decrypt(void *key, unsigned char *cipher, int len, \
unsigned char **plain);/*RSA*/

/* Block ciphers fucntions */
void bf_encrypt_decrypt(int mode, char *filein, \
char *fileout); /* BlowFish */
void des_encrypt_decrypt(int mode, char *filein, \
char *fileout); /* DES */
void idea_encrypt_decrypt(int mode, char *filein, \
char *fileout); /* IDEA */

/* Hash functions */
void md5cmp(char *file1, char *file2); /* MD5 */
void md5hash(char *filein); /* MD5 */

#include "rsa.c"
#include "block_ciphers.c"
#include "hash.c"
#include "misc.c"
-------------------end unisfed.h---------------------------------------

路过

雷人

握手

鲜花

鸡蛋

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

QQ|Archiver|手机版|小黑屋|软路由 ( 渝ICP备15001194号-1|渝公网安备 50011602500124号 )

GMT+8, 2024-5-20 16:43 , Processed in 0.054853 second(s), 5 queries , Gzip On, Redis On.

Powered by Discuz! X3.5 Licensed

© 2001-2023 Discuz! Team.

返回顶部