📄 rcrypt.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 + -