[net.lang.c] Data Encryption Techniques

gwyn@brl-vgr.ARPA (Doug Gwyn ) (04/12/84)

(You should probably also address questions like this to net.crypt.)

Vigenere encryption of a long file with a short key is pretty easy to
break.  A Kasiski analysis will show the key length, then each of the
monalphabetic encryptions can be attacked by frequency analysis.  The
"l*" in your algorithm may delay more advanced attacks if the analyst
does not know the algorithm you used, but he would almost certainly
be able to break the scheme with a modest amount of work.  If the
encryption algorithm is known to or discovered by the analyst, then
there are some more powerful techniques that make an automatic
cryptanalytic attack possible.

The real question is, are you trying to hide your sources from users
or from dedicated cryptanalysts?  If the former, several simple
methods are sufficient; if the latter, no known method is perfectly
safe (excepting those that involve secure storage of a large amount
of key).  One simplification you could make would be to use exclusive-
or of the key bits and the text bits; this is easy in C and faster
than the modulo method you used.

cbenson@reed.UUCP (04/15/84)

     I wrote the following program to fill my need for  some
form of security for my source code on our Altair. What I am
interested in is an evaluation by some  "knowledgeable  Joe"
as  to  the  relative security of my algorithm.  Please send
your response either by mail or this news  group.   (Perhaps
the news group would be the best way since we can never fig-
ure a path that works twice.)

     I probably misspelled the name of the  French  guy  who
gave  me  the  idea,  but  I doubt that this will affect the
operation of my program.

Any, and all, advice will be greatly appreciated.

/*
Jason E. Elliott	 9 March 1984
			13 March 1984
			14 March 1984

Program uses my own modification of the Vigenere algorithm for
enciphering and deciphering files.

If one file is specified on the command line then the file is
read, a temporary file is created, and the result of the cipher-
ment is written to the temporary file.  The temporary file is
the read and the contents are written back onto the original
file.  The temporary file is then unlinked.

If two files are specified on the command line then the first
file is read and ciphered, then the ciphered data is written
on the second file.

Warning:  The contents of the output file are lost upon 
	  invocation of this program.

Usage:  cipher f1 [f2]
*/

#include <stdio.h>
#define BUFLEN 16384

main (argc, argv)
int argc;
char *argv[];
{
register int l, i, f1, f2, sr;
char key[255], buf[BUFLEN], c;
if (argc == 1 || argc >3)
	{
	printf ("Usage:  cipher f1 [f2]\n");
	exit(1);
	}
f1 = openfl (argv[1]);
if (argc == 2)
	argv[2] = "temp.out.cpr";
if (!(f2 = creat (argv[2], 0600)))
	die (argv[2]);
system ("stty cbreak");
system ("stty -echo");
printf ("Enter Key:  ");
for (l=0;(key[l]=getchar ()) != '\n';l++)
	;
printf ("\nConfirm Key:  ");
for (i=0;i<l;i++) 
	{
	c = getchar ();
	if (c != key[i])
		{
		printf ("\nKey confirmation failed, exiting cipher...\n");
		leave (1);
		}
	}
printf ("\nWorking---\n");
while (sr = read (f1, buf, BUFLEN))
	{
	for (i=0;i<sr;i++)
		{
		if (!(i%l))
			rotate (key, l);
		buf[i] = (l*(key[i%l])-buf[i])%128;
		if (!(i%512))
			putchar ('.');
		}
	putchar ('*');
	if (!(write (f2, buf, sr)))
		wrerr (argv[2]);
	}
if (argc == 2)
	{
	close (f1);
	close (f2);
	f1 = openfl (argv[2]);
	if (!(f2 = creat (argv[1], 0600)))
		die (argv[1]);
	while (sr = read (f1, buf, BUFLEN))
		{
		putchar ('*');
		if (!(write (f2, buf, sr)))
			wrerr (argv[2]);
		}
	unlink ("temp.out.cpr");
	}
putchar ('\n');
leave (0);
}

rotate (string, len)
int len;
char string[];
{
int i;
char s1[255];
for (i=0;string[i] && i<len;i++)
	s1[i] = string[(i+1)%(len)];
stcopy (s1, string);
}

stcopy (s1, s2)
char *s1, *s2;
{
while (*s2++ = *s1++)
	;
}

int openfl (file)
char *file;
{
int fd;
if (!(fd = open (file, 0)))
	die (file);
return (fd);
}

wrerr (file)
char *file;
{
printf ("cipher:  write error on %s\n", file);
leave (1);
}

die (file)
char *file;
{
printf ("cipher:  cannot open %s\n", file);
leave (1);
}

leave (n)
int n;
{
system ("stty -cbreak");
system ("stty echo");
exit (n);
}
As is often said:  thanks in advance.

               Tootil-pip!

               Jason E. Elliott