⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcrypt.c

📁 非常经典的加密算法
💻 C
字号:
/* rcrypt.c
 *
 * jojo@farm9.com -- file encryption using Rijndael, 256 bit key
 *
 *   Handles odd file sizes using padding, creates a header that
 *   has file size and some random numbers.  Why?  Encryption blocks
 *   are 16 bytes, so resulting file size always a multiple of 16
 *   bytes.  Weird side effect of header -- encrypting same
 *   file with same key results in totally different output.
 *
 *   Hardcoded CBC mode with 256 bit key.  
 */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>

#include "rijndael-api-fst.h"


// 
// taken directly from rijndaeltest-fst.c
//
void rand_init(void)
{
	srand(time(NULL));
}

word32 rand_word32(void)
{
	return
	((word32)(rand() >> 7) << 24) | 
	((word32)(rand() >> 7) << 16) | 
	((word32)(rand() >> 7) << 8) | 
	(word32)(rand() >> 7);
}


// 
// jojo@farm9.com -- OK, someone else probably did this already,
//   but I couldn't find it...
//

static void usage() {
  printf( "Usage: rcrypt -e <key> <infile> [<outfile>]\n" );
  printf( "Usage: rcrypt -d <key> <infile> [<outfile>]\n" );
}

static BYTE convertKey( char k ) {
  int kval = k % 16;
  if ( kval < 10 ) {
    return( '0' + kval );
  } else {
    return( kval - 10 + 'A' );
  }
}

static void populateKeyMaterial( char* text, BYTE* key ) {
  char* textscanner = text;
  int i;
  for ( i = 0; i < MAX_KEY_SIZE; i++ ) {
    *key++ = convertKey( *textscanner );
    textscanner++;
    if ( *textscanner == 0 ) {
      textscanner = text;
    }
  }
}

int main ( int argc, char* argv[] ) {
  int r;
  BYTE block[4*4];
  BYTE keyMaterial[320];
  BYTE byteVal = (BYTE)'8';
  keyInstance keyInst;
  cipherInstance cipherInst;
  BYTE direction;
  BYTE header[100];
  FILE* fpin;
  FILE* fpout = stdout;
  int size;
  int fsize;
  int writesize;
#ifdef WIN32
  struct _stat statbuf;
#else
  struct stat statbuf;
#endif

  if (( argc != 4 ) && ( argc != 5 )) {
    usage();
    exit(1);
  }
  if ( strcmp( argv[1], "-e" ) == 0 ) {
    direction = DIR_ENCRYPT;
  } else if ( strcmp( argv[1], "-d" ) == 0 ) {
    direction = DIR_DECRYPT;
  } else {
    usage();
    exit(1);
  }
  fpin = fopen( argv[3], "rb" );
  fpout = stdout;
  if ( argc == 5 ) {
	  fpout = fopen( argv[4], "wb" );
	  if ( fpout == NULL ) {
		  printf( "** ERROR, cannot open output file '%s'\n", argv[4] );
		  exit(1);
	  }
  }

  populateKeyMaterial( argv[2], &keyMaterial[0] );

  r = makeKey(&keyInst, direction, 256, keyMaterial);
  if ( r != TRUE ) {
    printf( "** ERROR on makeKey: %d\n", r );
    exit(1);
  }
  r = cipherInit (&cipherInst, MODE_CBC, NULL);
  if ( r != TRUE ) {
    printf( "** ERROR on cipherInit: %d\n", r );
    exit(1);
  }

  if ( direction == DIR_ENCRYPT ) {
    // make header <file size> <random number>
    memset( block, 0, 16 );
#ifdef WIN32
    if (( _stat( argv[3], &statbuf ) == -1 ) || ( fpin == NULL )) {
#else
	if (( stat( argv[3], &statbuf ) == -1 ) || ( fpin == NULL )) {
#endif
		printf( "** ERROR, file '%s' not found **\n", argv[3] );
		exit(1);
	}
	printf( "file size is %d bytes\n", statbuf.st_size );
	rand_init();
	sprintf( header, "%d %d %d %d", statbuf.st_size, rand_word32(), rand_word32(), rand_word32() );
	memcpy( &block[0], &header[0], 16 );
	r = blockEncrypt(&cipherInst, &keyInst, block, 128, block);
	if ( fwrite( block, 16, 1, fpout ) != 1 ) {
		printf( "** ERROR writing output header\n" );
		exit(1);
	}
	// now we have that header out of the way, 
	// read in 16 byte blocks, encrypt each one
	while ( 1 ) {
		memset( block, 0, 16 );
		size = fread( block, 1, 16, fpin );
		if ( size > 0 ) {
			blockEncrypt( &cipherInst, &keyInst, block, 128, block );
			if ( fwrite( block, 16, 1, fpout ) != 1 ) {
				printf( "** ERROR writing data\n" );
				exit( 1 );
			}
		} else {
			break;
		}
	}
	fclose( fpin );
	fclose( fpout );
  } else {
    // decrypt header which is <file size> <random number>
	if ( fread( block, 16, 1, fpin ) != 1 ) {
		printf( "** ERROR reading input\n");
		exit(1);
	}
	r = blockDecrypt(&cipherInst, &keyInst, block, 128, block);
	fsize = atoi( block );
	printf( "file size is %d\n", fsize );
	// now we have that header out of the way, 
	// read in 16 byte blocks, encrypt each one
	while ( fsize > 0 ) {
		memset( block, 0, 16 );
		size = fread( block, 1, 16, fpin );
		if ( size > 0 ) {
			blockDecrypt( &cipherInst, &keyInst, block, 128, block );
			if ( fsize > 16 ) {
				writesize = 16;
			} else {
				writesize = fsize;
			}
			if ( fwrite( block, writesize, 1, fpout ) != 1 ) {
				printf( "** ERROR writing data\n" );
				exit( 1 );
			}
			if ( writesize != 16 ) {
				break;
			}
			fsize -= size;
		} else {
			break;
		}
	}

	fclose( fpin );
	fclose( fpout );
  }
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -