pcrypt

Antivirus, forensics, intrusion detection, cryptography, etc.
Message
Author
User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

pcrypt

#1 Post by rufwoof »

Oct 2019 version

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.
Attachments
pcrypt.gz
fake .gz, rename without that and chmod +x pcrypt to make executable
(19.21 KiB) Downloaded 215 times
Last edited by rufwoof on Thu 24 Oct 2019, 11:34, edited 5 times in total.

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#2 Post by rufwoof »

https://www.cloudcracker.com/ - for a fee offer a online cloud service that brute force crack attacks the following

WPA/WPA2
NTLM
SHA-512
MD5
MS-CHAPV2 (PPTP/WPA2-E)

pcrypt is resilient to such brute force attacks as some other meaningful output (decrypt) is just a likely as the actual unencrypted message. Given the universe of meaningful outcomes, the actual original content remains cloaked even if there was sufficient power/time to decipher all possibilities.

The downside of having to store key files has the benefit that you don't have to think up and remember passwords (which can lead to duplication (same password used to access multiple files/content)). With a unique key per file, even in the unlikely event that was cracked (extremely unlikely) that doesn't help in cracking any other files (as there's a single unique key for each file).
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

slavvo67
Posts: 1610
Joined: Sat 13 Oct 2012, 02:07
Location: The other Mr. 305

#3 Post by slavvo67 »

I like this idea. It'll have to wait until the weekend but I look forward to trying.....

bruno
Posts: 139
Joined: Thu 08 Mar 2012, 12:09
Location: Belgium

pcrypt otp

#4 Post by bruno »

Rufwoof, thanks for this great little utility, it works great on tahrpup605.
What would be even greater, is if you would make some gui so that OTP can be used with puppy as a way to communicate, that is: first create the one time pads, share them with your correspondent when you meet in person, and then later when you are in different locations, communicate encrypted by using those pads.
That would combine the unbreakable security of OTP encrypted communication, with the convenience of puppy.

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#5 Post by rufwoof »

Its quite useful when you have a confidential document/spreadsheet that you'd hate for others to see (financial accounts etc.). Keep one of the encrypted pair on googledrive or wherever, so no one with access to that can see it, and the key even on your laptop alone without that other half is pretty useless, so if your laptop is lost/stolen the spreadsheet is confidential/secret - unless of course they figure out your googledrive or wherever account login/password.

To open the spreadsheet pull the .fck file down from google to be alonside the .key file, click and the spreadsheets available to work on/use. When done encrypt again and upload the .fck to google, leave the .key as-is and its secure again. A nice aspect is that you don't even have to remember or think up a password (and each file is in effect secured by its own unique uncrackable password).

I now have mine set up in DebianDog Jessie to be a desktop icon that I can drag/drop a file onto which removes the original and creates the .fck and .key files. I've also associated .fck files to pcrypt so when the two files are alongside each other I can left click the .fck file and both the .fck and .key files are replaced by the unencrypted file.

slavvo67
Posts: 1610
Joined: Sat 13 Oct 2012, 02:07
Location: The other Mr. 305

#6 Post by slavvo67 »

I am able to use it in terminal, however I am getting an error with the gui. /usr/lib/gtkdialog/xml_info No such file or directory (line 77)

Same with xml_button-icon and xml_scalegrip. This is on Barry's QU 6.21 32 bit.

Also, do you know what kind of encryption it is using?

Thank you,

Slavvo67

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#7 Post by rufwoof »

slavvo67 wrote:I am able to use it in terminal, however I am getting an error with the gui. /usr/lib/gtkdialog/xml_info No such file or directory (line 77)

Same with xml_button-icon and xml_scalegrip. This is on Barry's QU 6.21 32 bit.

Also, do you know what kind of encryption it is using?

Thank you,

Slavvo67
Sorry Slavvo only noticed your posting just now.

The GUI no longer works for me either since I've moved over to DebianDog-Jessie. I just use the pcrypt binary alone now. Have it as a desktop icon so I can drag/drop onto that and have a file association to pcrypt for .fck files, so a right click open with pcrypt and the file is decrypted assuming the .key file is in the same directory.

Uses a key that's generated from /dev/urandom, where the key file is as long as the message (file being encrypted). The two are XOR'd. One time pad style - where provided the key file is truly random its the only proven uncrackable choice.

Typically I work on a confidential spreadsheet and once edits are complete I drag the saved file to the desktop pcrypt which creates a .fck and .key files. .fck can then be uploaded to googledrive or wherever, .key file retained securely (USB perhaps). When it comes to work on the spreadsheet again, download the .fck file from googledrive, move the .key file from USB to the same directory as the downloaded file, right click the .fck file and select open with pcrypt. ..... Repeat as required (new unique key for each saved version). Googledrive content is safe (encrypted content that's useless without the .key file), if laptop is stolen but USB is safe then the content remains safe (even if they have access to your googledrive account) and the content is recoverable even without the laptop. Loose the USB or if it stops working and your totally stuffed. Consequently I've been looking into RAID mirroring of USB's (two USB's connected via a USB hub where saving results in two copies, one copy on each of the two USB's). For now I'm still doing that copy of the key file to two USB's manually.

I run Linux in ram only, so there's no prospect of unencrypted recovery from the filesystem. If you run a full install/disk puppy/linux then if the laptop is stolen conceptually deleted files could be recovered/restored.

User avatar
6502coder
Posts: 677
Joined: Mon 23 Mar 2009, 18:07
Location: Western United States

#8 Post by 6502coder »

Just a couple of suggestions for options that might be useful in certain situations.

1. An option to NOT delete remove the original plaintext file after encryption. Bcrypt has this option.

2. An option to send the decrypted text to stdout, instead of to a file. This would allow sending the decrypt down a pipe, for example to "grep" or to "less", with the additional security that you never have the decrypted plaintext sitting on the hard disk or flash drive.

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#9 Post by rufwoof »

Useful suggestions. But just to clarify I wrote pcrypt for my own purposes ... which it fulfills and accordingly I won't be posting updates/changes/extensions. The C source code is included and can be modified/recompiled as deemed to be appropriate for your own needs.

I have been considering adding some changes for myself, such as including a secure delete of the original unencrypted file and adding a secure hdparm -r0 /dev/sdb and hdparm -r1 /dev/sdb type toggle to switch the USB from being read only to read/write as part of key file storage. Primarily with a view to storing more stuff (docs etc) in the Cloud so that if a virus does implement a disk encryption type payload then the USB's are less prone to being ransomed (original keys and encrypted cloud data providing the unencrypted data/docs content unimpeded by any virus). As part of that I'd include the writing of keys to two USB's simultaneously for better hardware (USB) failure protection (had been considering using RAID mirroring, but easier to provide that duplication functionality in code). If automated cloud transfer is also implemented then obviously it all becomes rather personal/specific and no longer appropriate for general application. Hence I don't want to have to maintain two different versions, one for others, one for myself.

slavvo67
Posts: 1610
Joined: Sat 13 Oct 2012, 02:07
Location: The other Mr. 305

#10 Post by slavvo67 »

Well, I like this project quite a bit so I hope you do enhance what you made and share it with the community. Pcrypt should live on and seems to be a quality security alternative. As you suggested in my PM, I've attached a link to your Pcrypt with a YAD wrapper. This places a desktop icon (a little red chili) which provides 4 options: Encrypt 1 file, Decrypt 1 file, Encrypt a directory, Decrypt a directory. The directory options simply use a for loop so the individual files still receive individual keys.

https://drive.google.com/file/d/0B672gI ... sp=sharing

slavvo67
Posts: 1610
Joined: Sat 13 Oct 2012, 02:07
Location: The other Mr. 305

#11 Post by slavvo67 »

I was thinking that changing the name of the file (hiding the name) before encrypt would be another interesting step in the encryption process. Converting the true file name back upon decryption. :idea:

User avatar
6502coder
Posts: 677
Joined: Mon 23 Mar 2009, 18:07
Location: Western United States

using bogus file names

#12 Post by 6502coder »

slavvo67 wrote:I was thinking that changing the name of the file (hiding the name) before encrypt would be another interesting step in the encryption process. Converting the true file name back upon decryption. :idea:
This is a good idea and one that I use myself sometimes.
But if you are encrypting LOTS of files, how do you keep track of what their original names were?
How do you know which file is which when the names no longer tell you what's in them? :?

slavvo67
Posts: 1610
Joined: Sat 13 Oct 2012, 02:07
Location: The other Mr. 305

#13 Post by slavvo67 »

Well, my thought is upon name change, having a file that would cross reference the old file name against the new file name. Maybe a front-end gui that would call the file by its original name vs the encrypted name. Of course, if you blow up your Quirky or other puppy save, all is lost. :lol:

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#14 Post by rufwoof »

For Tahr 64 bit 6.0.5 and the sfs as per the first post ... and the /usr/sbin/pcrypt executable file doesn't run.

Load your Devx and cc pcrypt.c to create a new a.out and replace /usr/sbin/pcrypt with that (cd /usr/sbin; rm pcrypt; mv a.out pcrypt) ... and it all seems to work ok (drag /usr/share/applications/pcrypt.desktop to the desktop for ease of use).

Thereafter drag a file to that desktop icon and it forms the .fck and .key files (original unencrypted file removed). Drag the .fck file back to the desktop icon and the original file is restored.

Remember security is a process not a package. For a single user desktop setup that the likes of Puppy serves, target a data concentric security approach.

Tips :

1.

For MBR based systems ensure you also have a copy of your MBR backed up

Code: Select all

MBR Total Size
446 + 64 + 2 = 512
Where
446 bytes – Bootstrap
64 bytes – Partition table
2 bytes – Signature

Backup MBR and keep in safe read only storage (assuming MBR is on drive sda)

	dd if=/dev/sda of=/safe/location bs=512 count=1

Restore MBR

	dd if=/safe/location of=/dev/sda bs=512 count=1
and periodically check that MBR (a simple backup and checksum of that with a known good copy even at each reboot is a relatively small overhead).

2. Ideally don't use a disk based swap file or partition ... memory is cheap, and if your HDD falls into the wrong hands the swap file/partition can be read.

3. System software is relatively inexpensive to replace, especially if it can be installed quickly as per Puppy. Give that much less focus than your data files, that might be invaluable/irreplaceable. Apply a mental thought along the lines of if this were a laptop system that was left on a train, how concerned would I be and how would I like the system/data setup so as to best protect myself.

Most data files could likely be left as-is, notes, records ... etc. things that you wouldn't be too bothered about others seeing. Some data you would rather others couldn't see/access and this is where pcrypt can help. Store keys (.key) and encrypted files (.fck) separately, ideally one being on a USB (along with backups of that USB) and only merge (decrypt) the two in ram ... such as Puppy's root folder before editing etc. and reforming (re-encrypt) and separating the two again.

4. Ensure you have a firewall activated. Yes you might be behind a router that has a firewall, I have two such routers with the wireless off behind the second one (that I'm hardwired into), but I still have a PC firewall as well. If one of the other family members systems are breached then that firewall provides protection against that.

5. For online banking, cold boot a pristine factory fresh puppy, use a pristine factory fresh browser (with no plugins or addons installed) and go directly to your bank/stockbrokers web site, nowhere else before or after. Even old unpatched versions of software run that way are relatively secure as hackers have little opportunity to break into that.

For more general browsing/usage, a savefile and more conventional boot is fine/convenient. Little different to if you were using a PC at your local library or in a internet cafe.

6. 7. 8. & 9. - backups, backups, backups, backups ... multiple backup copies - with some stored offsite. System backups are much less important than irreplaceable/invaluable data backups. Personally I like to use mksquashfs for backups

mksquashfs /mnt/sda1 backupxxx.sfs (to create)
unsquashfs -f -d /mnt/sda1 backupxxx.sfs (to restore)

To reiterate, security is a process, not a package. Puppy running apps as root is fine providing your security process is OK. Generally security comes with complexity and barriers, however the above are reasonable security practices with relatively light overheads. Puppy running as root, updates/patches not applied ... etc. with security in mind, can be a lot more secure than PC's that are assumed to be safe, but have been used by many and/or browsed here/there/everywhere with changes being persistent that could have had a weakness that was breached at any point in the past, and where the user gives little thought to security (believing they are safe) ... until after the event.
Last edited by rufwoof on Sat 22 Jul 2017, 21:35, edited 1 time in total.

User avatar
rcrsn51
Posts: 13096
Joined: Tue 05 Sep 2006, 13:50
Location: Stratford, Ontario

#15 Post by rcrsn51 »

rufwoof wrote:If one of the other family members systems are breached then that firewall provides protection against that.
Just out of curiosity, what does "breached" mean and how do you know that a firewall protects you against it?

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#16 Post by rufwoof »

Virus scanners typically identify known virus and search for virus like patterns.

A breached system is a either knowingly or not infected system that could potentially be exploited by hackers. When knowingly infected typically a virus scanner will detect that. Unknown penetrations are a concern as they might be dormant or doing relatively light tasks perhaps to spread further, such as seeking out LAN ports that are open to spread through in a unobserved manner.

Often firewalls protect against inbound traffic but do little to monitor outbound. Once in a virus might request things from outside and its return traffic is more accepted as being valid traffic ... which could be a payload program that the internal program runs from the inside.

Many program providers conveniently publish security risks, typically after they've figured out a patch (but not always and some publish risks even before patches are available). Which are a good source for hackers as they are given pointers of where to look for potential exploits to be applied and on which versions of systems (that might not have been patched in a timely manner).

Having a firewall running on each PC on a LAN is better than not. More so if one or more are Puppy's as that provides potentially easier means to break out (such as firefox running as root with a known vulnerability). As a for-instance, when gcmartin was hereabouts he was shocked at how quickily/easily it was for a total stranger to ask why he was running as root and reveal gcmartin's personal address to him. IIRC scared the pants off him and g subsequently totally revised his setup/security practices.

User avatar
rcrsn51
Posts: 13096
Joined: Tue 05 Sep 2006, 13:50
Location: Stratford, Ontario

#17 Post by rcrsn51 »

Thanks. Can you give an example? How would a breached computer on my network attempt to attack my computer and how would a firewall on my computer stop it?

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#18 Post by rufwoof »

First post updated for a more recent version and a minor (cosmetic) bug fix.
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#19 Post by rufwoof »

As a alternative to using /dev/urandom to source random data, I quite like this ... (set C= ... number of 65535 bytes blocks)

Code: Select all

dd status=none if=/dev/urandom bs=65535 count=$C | pv --bytes | \
 openssl enc -aes-256-ctr \
 -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" \
 -nosalt > randomfile.bin 2>/dev/null
random key encrypted /dev/urandom data :)

Using -nosalt as otherwise (default) the output can contain predictable content (such as 'Salted').

dd using 65536 byte blocks is appropriate when using pipes as the default linux pipe block size is 65536.

Unlike /dev/random, /dev/urandom will not block when it has no more entropy, but instead continues to output pseudo-random data. By combining urandom with encoding of that urandom data using a aes-256 random key, that's close to continuing to be random.
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#20 Post by rufwoof »

Here are more recent versions of pcrypt.c, and a wrapper script that prepares the randomfile.bin that contains the random data

pcrypt.c

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

/************************************************************/
/* Rufwoof Jan 2016                                         */
/* 2019 revised to use randomfile.bin as source of random data */

/************************************************************/

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("\nFor 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' ) {
   if ((f = fopen("randomfile.bin","rb")) == NULL ) { 
      printf("Can't open randomfile.bin\n");
      return(6);
   }
   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"); Dec 2019 */
  pcnt=statbuf.st_size/100;
  ccnt=1;
  percent=0;
  printf("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("\r%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("\rDone\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);
  if ( DOING == 'e' ) {
     fclose(f);
  }
  fclose(mykeyfile);
  fclose(sourcefile);
  fclose(destfile);
  if ( DOING == 'd' ) {  /* remove input file(s) */
   ret=remove(keyfile);
  }
  ret=remove(argv[1]);
}
Wrapper script

Code: Select all

#!/bin/ash

# Rufwoof Dec 2019

# crypt shell script, encrypts (and decrypts when a .fck file suffix)
# Intended to be run in ram+encrypted swap (so no hdd footprints left)
# Master/Main (wrapper) script that calls pcrypt C program binary.
# On encryption creates a .fck and a .key files. No password needs to
# be remembered, simply bringing the two files back together again and
# running crypt against the .fck file - restores the clear text file.
# Individually both .fck and .key files are useless without the other
# so when stored separately they are secure (cannot be cracked).


if [ -z $1 ]; then
	echo " "
	echo "Usage : $0 <filename>"
	echo "if filename has a .fck suffix then decrypts"
	echo " "
	echo "Future proof One-Time-Pad style encryption"
	echo " "
	echo "We use /dev/urandom for random data which unlike /dev/random will not block"
	echo "if entropy is exhausted, but instead fall back to strong pseudo-random data"
	echo "when real random data is exhausted. As one-time-pad encryption requires a"
	echo "'key' the same size or larger than the file being encrypted, and hence"
	echo "entropy may be being exhausted (pseudo random data being produced by"
	echo "urandom) we further encrypt the urandom data using a aes-256-ctr random key."
	echo " "
	echo "Encryption should be performed totally in ram (or ram + encrypted swap) so"
	echo "not to leave any remnants (such as might be recovered from hdd). Even with"
	echo "unlimited resources, brute forcing one-time-pads will yield multiple"
	echo "potential solutions, but where the precise solution cannot be identified"
	echo "(mathematically impossible to crack/remains unknown)."
	echo " "
	exit
fi

if [ ! -f $1 ]; then
	echo "File $1 not found"
	exit
fi

# Inspect file extension
filename=$(basename "$1")
ext="${filename##*.}"

if [ "$ext" = "fck" ]; then
	# decrypt
	pcrypt $1
else
	# encrypt
	
	# generate random byte stream equal or longer than the file to be encrypted
	
	FILESIZE=$(stat -c%s "$1")
	C=`expr $FILESIZE / 65536` # we use a 65535 byte blocksize for dd (faster and matches linux pipe 65536 byte blocksize)
	C=`expr $C + 1`            # pad out (otherwise rounding will make it too short)
	O=`expr $C \* 65536`
	echo "Generating ${O} bytes of random key encrypted /dev/urandom data ..."
	# What we're doing next is using /dev/urandom as a source of random
	# bytes, writing those to randomfile.bin, but where we aes-256-ctr
	# encrypt those bytes using a random generated key, so even
	# if the /dev/urandom source of bytes was /dev/zero instead, it would
	# still be 'random' data being written to randomfile.bin.
	# dd with status=none is used to supress output of information
	# We size randomfile.bin content to be marginally larger than the
	# number of bytes required to one-time-pad. We use a 65536 byte block
	# size for the dd as that matches Linux pipe buffer size (faster).
	dd status=none if=/dev/urandom bs=65536 count=$C | pv --bytes | \
	openssl enc -aes-256-ctr \
	-pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" \
	-nosalt > randomfile.bin 2>/dev/null
	# -nosalt is used as otherwise 'salted' occurs in the random sequence
	echo "Encrypting ..."
	pcrypt $1
	rm randomfile.bin	# being (or rather should be running) in ram,
				# simple removal suffices (hdd would require shred)
fi
Note that I'm running OpenSSL 1.1.1d
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

Post Reply