Fatdog 8 pre-built binary as attached to this post
Added additional randomisation. Skips a random 1 to
4 number of /dev/urandom bytes before hitting the
actual random byte used for the XOR - where that 1
to 4 random value is seeded by time().
Fixed very small files returning a 128% progress value
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
/************************************************************/
/* Rufwoof Jan 2016 */
/* Run this program once to encrypt and again, using the */
/* key created by encryption to decrypt. */
/* Input to be encrypted should have been compressed first */
/* in order to normalise the content (approximately equal */
/* number of occurrences of all bytes 0..255) */
/* Makes a key using random numbers. */
/* The random number generator is sourced from /dev/urandom */
/* That random sequence is then XOR'd with the message */
/* (file content) to produce the output encrypted file */
/* (that has a .fck suffix). The keyfile is also created */
/* (.key suffix), which is required to decrypt the encoded */
/* .fsk file content (which is achieved by XOR'ing the .fsk */
/* file content with the .key file content). */
/* Strives to preserve same file permissions as original */
/* Input file(s) are deleted */
/*
Compiled using ..
install musl-lib and ...
musl-gcc -static -o pcrypt pcrypt.c
also ran through upx --ultra-brute
*/
/*
Oct 2019. Fixed cosmetic bug where for very small
files Progress could indicate > 100%
*/
/************************************************************/
int main(int argc,char **argv) {
struct stat statbuf;
struct stat statbufkeyfile;
int key, data, output, ret, percent;
double count=0, ccnt, pcnt;
char keyfile[1024], outfile[1024], *point, DOING;
FILE * mykeyfile, * sourcefile, * destfile, * f;
if(argc<2) {
printf("File encrypt/de-encrypt using a key size equal to message (file) size\n");
printf("For encryption\n");
printf(" pcrypt non-encrypted-file\n");
printf(" creates a encrypted file with the same name and a .fck suffix\n");
printf(" and a associated .key suffix keyfile - that should be kept safe\n\n");
printf("The input file to be encrypted should be pre-compressed beforehand\n");
printf("(as that normalises (near equal numbers of bytes 0..255) the data)\n\n");
printf("For de-encryption\n");
printf(" pcrypt encrypted-file.fck\n");
printf(" the .key keyfile that was used to encrypt must be in the same directory\n");
return(0);
}
/* Bail out if the wrong number of arguments are used. */
if(argc>2) {
printf("Too many arguments.");
sleep(3);
return(1);
}
/* get the size of the source file */
if ((sourcefile = fopen(argv[1], "rb")) == NULL) {
printf("Can't open source file.\n");
return(4);
}
fflush(sourcefile);
fstat(fileno(sourcefile), &statbuf);
fclose(sourcefile);
if ( ! S_ISREG(statbuf.st_mode) ) {
printf("Not a regular file pcrypt only works on files\n");
return(6);
}
sourcefile=fopen(argv[1],"rb");
DOING='e'; /* default is to encrypt */
if ((point = strrchr(argv[1],'.')) != NULL ) {
if (strcmp(point,".fck") == 0) {
DOING='d'; /* de-encrypting */
}
}
if ( DOING == 'e' ) {
snprintf(outfile, sizeof outfile, "%s.fck", argv[1]);
snprintf(keyfile, sizeof keyfile, "%s.key", argv[1]);
mykeyfile = fopen(keyfile,"wb");
} else {
snprintf(outfile, sizeof outfile, "%s", argv[1]);
outfile[strlen(outfile)-4] = 0; /* strip of .fck suffix */
snprintf(keyfile, sizeof keyfile, "%s.key", outfile);
if ((mykeyfile = fopen(keyfile,"rb")) == NULL ) {
printf("Can't open key file.\n");
return(5);
}
/* check keyfile and .fck file sizes are the same i.e. look like valid partners */
fflush(mykeyfile);
fstat(fileno(mykeyfile), &statbufkeyfile);
fclose(mykeyfile);
if ( statbufkeyfile.st_size != statbuf.st_size ) {
printf("key file and .fck filesize differ\nperhaps corrupt or incorrect pairing\nprogram halting\n");
return(5);
}
mykeyfile=fopen(keyfile,"rb");
}
destfile=fopen(outfile,"wb");
f = fopen("/dev/urandom", "rb");
pcnt=statbuf.st_size/100;
ccnt=1;
percent=0;
printf("Processing : 0%%");
fflush(stdout);
/* Use the key to encrypt/decrypt the source file. */
while (count < (statbuf.st_size)) {
if ( DOING == 'd' ) {
key=fgetc(mykeyfile); /* decrypting */
} else {
key=fgetc(f);
fprintf(mykeyfile,"%c",key); /* store to .KEY file */
}
/* progress indicator */
ccnt++;
if ( ccnt > pcnt ) {
ccnt=1;
percent++;
if ( percent > 100 ) {
percent=100;
}
printf("\rProcessing : %i%%",percent);
fflush(stdout); /* have to flush otherwise not shown (unless a \n included) */
}
data=fgetc(sourcefile);
output=(key^data);
/* XOR the data byte once with a byte from a key and it encrypts. */
/* XOR the resultant byte again with the same byte from the same key, and it decrypts. */
fputc(output,destfile);
count++;
}
printf("\nDone\n");
/* update to the same uid/gid as the source file */
fchown(fileno(destfile),statbuf.st_uid,statbuf.st_gid);
/* update the permissions */
fchmod(fileno(destfile),statbuf.st_mode);
fclose(f);
fclose(mykeyfile);
fclose(sourcefile);
fclose(destfile);
if ( DOING == 'd' ) { /* remove input file(s) */
ret=remove(keyfile);
}
ret=remove(argv[1]);
}
Original 2016 post content follows ...
===
pcrypt single file encryption. pcrypt generates a one time keyfile that is the same size as the message (file) using /dev/urandom sourced random data. /dev/urandom utilises hardware/environment to induce randomness - in effect purely random. For truly random keys One Time Pad encryption (with keysize = message size) is proven uncrackable.
Pcrypt uses a key that's generated from /dev/urandom ... as close to truly random as you might get as it contains elements of timing and system events such as disk spinning, mouse movements ...etc.
SFS located here http://murga-linux.com/puppy/viewtopic. ... 776#881776
Puppy's small size makes it great for running purely in ram. If you store .fck (encrypted) file/data on a remote server (cloud - such as googledrive) and keep the associated .key file on a USB, then you can download the file (into ram) and decrypt that (using the key on the USB) and work on the file ... and then re-encrypt and upload the revised version to the cloud (and replace the old key with the new one on the USB) ... all without any decrypted data being recorded on your local laptop/PC. Once powered off the ram is cleared such that if the laptop is stolen your data is not available to the thief.
The .key file is useless without the associated .fck (encrypted data) file. The .fck file is useless without the associated .key file. And run in ram no cache of the unencrypted data remains available once powered down.
Each file has its own unique key (one time pad), and you don't have to worry about remembering passwords. The only downside is that each file takes up twice the amount of disk space, one for the encrypted data, the other for the key - however more modern hardware usually have copious amounts of disk space.