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

📄 3des.c

📁 des的变形算法
💻 C
字号:
/*
 *                        A C shell for DES486.asm.
 *            This one implements Triple DES in Stream Cipher Mode
 *              with IV/Cipher Feedback (for Error Propogation).
 *            This program is designed to be suitable for long-term
 *                        storage of sensitive data.
 */

#define TRIPLE_DES
#define BUFFERSIZE 512
#define DOTSIZE (10000/BUFFERSIZE) /* put dot on screen every 10K */

#include "3des.h"        /* holds prototypes for asm functions */
#include <stdio.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <dir.h>
#include <dos.h>
#include <io.h>
#include <mem.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char byte;
typedef unsigned char *byteptr;

extern int _fmode;
extern byteptr getpassword(byteptr password, int hidden);

int crypt_to_source(void);      /* same func for encrypt & decrypt */
int crypt_to_dest(void);        /* same func for encrypt & decrypt */
int (*action)(void);            /* assignable pointer */

void who_i_am(void);
void parsefile(char *filename, char *iv);
void xorbuf(byteptr output, byteptr input, int count);
int getstring(char *strbuf, int maxlen, int echo);

unsigned char password[8];
byte buffer[BUFFERSIZE];
struct fatinfo dtable;
struct ftime filetime;
struct ffblk searchbuf;
char tempname[13+20];   /* 20 chars for path */
int dest_specified;
char dest_path[20];
FILE *fp1,*fp2;
long oldsize,newsize,l;
int on_decrypt=0;
char *diskfullmsg="Disk full:   ";
byte iv[8];             /* the initialization vector */

int main(int argc, char *argv[])
 {
   int argcount;
   char **argvec;
   char drivename=0, drivebuf[3];
   int old_drive;
   char pathname[MAXDIR],old_path[MAXDIR],pathbuf[MAXDIR];
   char filename[13];
   char namebuf[MAXFILE],extbuf[MAXEXT];
   char *c,*cp,ch;
   int i,j,result,done,count,hidden;

   if((result=cpu())<486)
    {
      who_i_am();
      printf("This program needs a 486 cpu to run.\n");
      printf("Can't run on your %d\n",result);
      return(1);
     }

   dest_specified=0;   /* default: over-write the input file */
   action=crypt_to_source;
   result=0;    /* flag: no errors in cmd line */
   count=0;     /* flag: set when crypt or decrypt specified */
   hidden=0;    /* flag: if prompting for password, don't hide input */

   argcount=1;
   argvec=argv+1;
   while(argvec[0][0]=='-')
    {
      switch (argvec[0][1])
       {
         case 'd':      /* decrypt */
         case 'D':
          count++;
          on_decrypt=1;
          break;
         case 'c':      /* crypt */
         case 'C':
          count++;
          break;
         case 'h':      /* hide the password */
         case 'H':
          hidden=1;
          break;
         case 'o':      /* output path specified */
         case 'O':
          dest_specified=1;
          action=crypt_to_dest;
          strncpy(dest_path,&argvec[0][2],19);
          strupr(dest_path);    /* make upper-case */
          i=0;
          while(dest_path[i])
                ++i;
          --i;
          if(dest_path[i]!='\\' && dest_path[i]!=':')
           strcat(dest_path,"\\");      /* ensure path properly terminated */
          break;
         default:
          result=1;     /* invalid switch is error */
        }
      ++argcount;
      ++argvec;
     }
   if(count==0)         /* encrypt/decrypt not specified */
    result=1;
   if(argc-argcount<1)  /* too few arguments */
    result=1;

   if(result)   /* print usage screen and die */
    {
      who_i_am();
      return(1);
     }


                /* parse the password */

   printf("Enter password 1: ");
   cp=getpassword(password,!hidden);
   if(cp==0) return(1);             /* exit if no password given */
   schedule(cp,en_keytbl);          /* make 16 rounds of keys */
   printf("Enter password 2: ");
   cp=getpassword(password,!hidden);
   if(cp==0) return(1);             /* exit if no password given */
   schedule(cp,de_keytbl);          /* make 16 rounds of keys */


        /* Now deal with drives and directories */

   old_drive=getdisk();         /* get current drive */
   getcwd(old_path,MAXDIR);     /* get current directory */
   drivename=old_drive+'A';
   memset(pathname,0,MAXDIR);
   memset(filename,0,13);

   result=fnsplit(argv[argc-1],drivebuf,pathbuf,namebuf,extbuf); /* filespec */
   if(result&DRIVE)
    drivename=drivebuf[0];
   if(result&DIRECTORY)
    {
      strcpy(pathname,pathbuf);
      if(pathname[strlen(pathname)-1]=='\\')
       pathname[strlen(pathname)-1]=0;    /* chdir barfs on trailing '\' */
     }

   if(drivename)
    setdisk((int)toupper(drivename)-'A');
   if(pathname[0])
    if(chdir(pathname))
     {
       setdisk(old_drive);
       printf("Can't find path %s\\ on drive %c:\n",pathname,drivename);
       for(i=0;i<BUFFERSIZE;++i)
        buffer[i]=0;    /* zero out password spec in buffer */
       killkey();        /* zero out key schedule */
       return(1);
      }
   strcpy(filename,namebuf);
   strcat(filename,extbuf);


                /* main processing loop */

   result=0;
   count=0;
   done=findfirst(filename,&searchbuf,0);
   while(!done&&result>=0)
    {
      ++count;
      result=do_process();
      done=findnext(&searchbuf);
     }
   printf("\n%d %s found.\n",count,count==1?"file":"files");
   setdisk(old_drive);
   chdir(old_path);

   for(i=0;i<BUFFERSIZE;++i)
    buffer[i]=0;        /* in case no files, kill password spec in buffer */
   killkey();           /* zero out key schedule */
   return(0);
  }                     /* normal return from main() */


/*  do_process() Return from this func can be:
  ( 0) normal successful file processing
  ( 1) non-fatal error (continue trying other files)
  (-1) fatal: give up trying other files
*/
int do_process()
 {
   int result;
   int i,j;

   /* may we over-write? */
   if((searchbuf.ff_attrib & FA_RDONLY) && !dest_specified)
    {
      printf("%s:   Access Denied\n",searchbuf.ff_name);
      return(1);
     }

   fp1=fopen(searchbuf.ff_name,dest_specified?"rb":"r+b");
   if(fp1==NULL)
    {
      printf("Can't open %s for input\n",searchbuf.ff_name);
      return(1);
     }

   if(dest_specified)
    {
      strcpy(tempname,dest_path);
      strncat(tempname,searchbuf.ff_name,32);
      fp2=fopen(tempname,"wb");
      if(fp2==NULL)
       {
         printf("Can't open %s for output\n",tempname);
         fclose(fp1);
         return(1);
        }
     }
   getftime(fileno(fp1),&filetime);         /* save file time & date */

   parsefile(searchbuf.ff_name,iv); /* set IV seed from filename */

   if((result=action())!=0)    /* encrypt/decrypt done here */
    {
      printf("Aborted\n");
      fclose(fp1);
      if(dest_specified)
       { fclose(fp2);
         unlink(tempname);         /* erase temp file */
        }
      return(result);
     }

   setftime(fileno(dest_specified?fp2:fp1),&filetime); /* reset to old time */
   if(dest_specified)
    fclose(fp2);
   fclose(fp1);

   printf("done\n");
   return(0);                           /* normal successful return */
  }




int crypt_to_source()
 {
   int readsize, count,chunksize, blocknum=0;
   long readpos=0, writepos=0;
   byte *buf;

   printf("%s %s:   ",on_decrypt?"Decrypting: ":"Encrypting: ",\
    searchbuf.ff_name);
   while((count=fread(buffer,1,BUFFERSIZE,fp1))>0)
    {
      readsize=count;
      readpos += readsize;
      buf=buffer;
      while((chunksize=min(count,8))>0)
       {
         mov64(block,iv);
         encrypt_block();       /* encrypt IV. Result is in block[] */
         decrypt_block();
         encrypt_block();
         if(on_decrypt)         /* we're decrypting */
          xor64(iv,buf);
         xor64(buf,block);
         if(!on_decrypt)        /* we're encrypting */
          xor64(iv,buf);
         count -= chunksize;
         buf += chunksize;
        }
      fseek(fp1,writepos,SEEK_SET);
      if(fwrite(buffer,1,readsize,fp1)!=readsize)
       {
         fprintf(stderr,diskfullmsg);
         return(-1);    /* fatal error */
        }
      writepos += readsize;
      fseek(fp1,readpos,SEEK_SET);
      if(++blocknum==DOTSIZE)
       {
         blocknum=0;
         fputc('.',stdout);  /* show user we're still alive... */
        }
     }
   fflush(fp1);
   return(0);
  }

int crypt_to_dest()
 {
   int readsize, count,chunksize;
   int blocknum=0;
   byte *buf;

   printf("%s %s to %s: ",on_decrypt?"Decrypting":"Encrypting",\
    searchbuf.ff_name,tempname);
   while((count=fread(buffer,1,BUFFERSIZE,fp1))>0)
    {
      readsize=count;   /* save for file writes */
      buf=buffer;
      while((chunksize=min(count,8))>0) /* do while (buffer) */
       {
         mov64(block,iv);
         encrypt_block();
         decrypt_block();
         encrypt_block();
         if(on_decrypt)   /* we're decrypting */
          xor64(iv,buf);
         xor64(buf,block);
         if(!on_decrypt)   /* we're encrypting */
          xor64(iv,buf);
         count -= chunksize;
         buf += chunksize;
        }
      if(fwrite(buffer,1,readsize,fp2)!=readsize)
       {
         fprintf(stderr,diskfullmsg);
         return(-1);    /* fatal error */
        }
      if(++blocknum==DOTSIZE)
       {
         blocknum=0;
         fputc('.',stdout);  /* show user we're still alive... */
        }
     }
   fflush(fp1);
   fflush(fp2);
   return(0);
  }

void who_i_am()
 {
   clrscr();
   printf("\n3DES: a fast, secure stream-mode Triple-DES encryption program for 486 ISA PCs.\n");
   printf("   By Steve Allen     73277.620@compuserve.com (CIS 73277,620)\n");
   printf("\nUsage: 3DES -c|d -h [-oOUTPUTPATH] filespec\n");
   printf("-c -d crypt or decrypt (must specify)\n");
   printf("-h hide password input\n");
   printf("[-oOUTPUTPATH] place output file here\n");
   printf(" (If OUTPUTPATH not specified, file is over-written)\n");
   printf("Wildcards OK in filespec\n\n");
   printf("    Password usage:\n");
   printf("1: password_text         uses password_text for password\n");
   printf("2: #password_text        uses MD5 hash of password_text for password\n");
   printf("3: @filename[,offset]    uses data in file [at optional offset] for password\n");
   printf("4: !filename[,offset]    decrypts data in file [at optional offset] for password\n");
  }

/* seed the IV with the filename */
void parsefile(char *filename, char *iv)
 {

   char *cp;
   int i,j;

   cp=filename;
   for(i=0,j=0;i<8&&cp[i];++i)
    iv[j++]=cp[i];
   while(i<13&&cp[i])
    {
      iv[j%8]^=cp[i];   /* mash extra chars into 1st 8 bytes */
      ++i;
      ++j;
     }
   while(j<8)
    iv[j++]=0;
  }

⌨️ 快捷键说明

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