自制基於rc5的一個文件加密小程序

//#include
#include<afx.h>
#include <stdio.h>

#define KEYSIZE 16     /* size of key, in bytes */

#if !defined UINT
typedef unsigned int UINT; /* Should be 32-bit = 4 bytes        */
#endif

typedef enum { ShiftLeft, ShiftRight } ShiftDir;

typedef enum { KeyWords = KEYSIZE / 4,
           NumRounds = 15,  /* Number of cryptographic rounds  */
           TableSize = 32   /* size of table = 2 * (NumRounds + 1) */
} bogus;

UINT Table[ TableSize ];
UINT L[KeyWords];

UINT ROT(const UINT x, const UINT y, const ShiftDir dir)
{

  const unsigned int ShiftAmt = (y & (unsigned int)0x1f);
  const unsigned int ShiftBack = 0x20 - ShiftAmt;
  unsigned int result;
 
  if (dir == ShiftLeft)
    result = (x << ShiftAmt) | (x >> ShiftBack);
  else
    result = (x >> ShiftAmt) | (x << ShiftBack);
  return result;
} /* ROT */
//設置密鑰
void SetKey( unsigned char KeyChar )
{
    static unsigned int KeyCntr;
    static unsigned int Shift;

    int ix = KeyCntr >> 2;

    /* this is simply a machine independent way of setting L[i] to
       KeyChar[i], without being affect by "endianess". */
    L[ ix ] = (L[ ix ] & (~(0xff << Shift))) | (KeyChar << Shift);

    Shift = (Shift + 8) & 0x1f;
    KeyCntr = (KeyCntr + 1) & (KEYSIZE - 1);  /* This Depends on KEYSIZE being */
                                              /* a power of two.  The & will   */
                                              /* cause the KeyCntr to wrap     */
                                              /* and only have values in the   */
                                              /* range 0..KEYSIZE-1.           */
}  /* RC5_Crypto */

//雙字加密函數
/* 2 UINT: input plain text, output encrypted text    */
void encrypt(UINT *PlainText, UINT *CryptoText)
{

  UINT i, temp;
  UINT A;
  UINT B;

  A = PlainText[0] + Table[0];
  B = PlainText[1] + Table[1];

  for (i = 1; i <= NumRounds; i++) {
    temp = i << 1;
    A = ROT(A^B, B, ShiftLeft) + Table[temp];
    B = ROT(A^B, A, ShiftLeft) + Table[temp+1];
  }
  CryptoText[0] = A;
  CryptoText[1] = B; 
}  /* RC5_Cypto::encrypt */

//雙字解密函數
/* 2 UINT input encrypted text, output plain text    */
void decrypt(UINT *CryptoText, UINT *PlainText)
{
  UINT i, temp;
  UINT B;
  UINT A;

  B = CryptoText[1];
  A = CryptoText[0];

  for (i=NumRounds; i > 0; i--) {
    temp = i << 1;
    B = ROT(B - Table[temp+1],A, ShiftRight)^A;
    A = ROT(A - Table[temp],  B, ShiftRight)^B;
  }
  PlainText[1] = B-Table[1];
  PlainText[0] = A-Table[0]; 
}     /*  decrypt */
//初始化函數
void setup() /* secret input key K[0...KEYSIZE-1]   */
{
  /* magic constants (courtesty of RSA) */
  static const UINT ROM[ TableSize ] = { 0xb7e15163, 0x5618cb1c, 0xf45044d5,
                                         0x9287be8e, 0x30bf3847, 0xcef6b200,
                                         0x6d2e2bb9, 0x0b65a572, 0xa99d1f2b,
                                         0x47d498e4, 0xe60c129d, 0x84438c56,
                                         0x227b060f, 0xc0b27fc8, 0x5ee9f981,
                                         0xfd21733a, 0x9b58ecf3, 0x399066ac,
                                         0xd7c7e065, 0x75ff5a1e, 0x1436d3d7,
                                         0xb26e4d90, 0x50a5c749, 0xeedd4102,
                                         0x8d14babb, 0x2b4c3474, 0xc983ae2d,
                                         0x67bb27e6, 0x05f2a19f, 0xa42a1b58,
                                         0x42619511, 0xe0990eca };
  UINT i;
  UINT A;
  UINT B;
  UINT j;
  UINT k;
 
  /* Copy "ROM" into "RAM" */
  for (i=0; i < TableSize; i++)
    Table[i] = ROM[i];

  /* 3*t > 3*KeyWords */

  A = 0;
  B = 0;
  i = 0;
  j = 0;

  for (k=0; k < 3*TableSize; k++) {
    Table[i] = ROT(Table[i]+(A+B),3, ShiftLeft);
    A = Table[i];
    L[j] = ROT(L[j]+(A+B),(A+B), ShiftLeft); 
    B = L[j];
    i= (i+1) & (TableSize-1);  /* using '&' for % only works for powers of 2  */
    j= (j+1) & (KeyWords-1);
  }
}     /* setup */

//文件加密函數
bool EncryptFile(char *pchFileName)
{
    CFile    fileb4;
    CFile    encryptfile;
    CFileException e;
    char    pchEncryptFileName[100];
    sprintf(pchEncryptFileName, "$%s", pchFileName);

    if( !fileb4.Open( pchFileName, CFile::modeRead | CFile::shareDenyNone, &e ) )
    {
        printf("%s could not be opened %d/n", pchFileName, e.m_cause);
        return false;
    }
    if ( !encryptfile.Open( pchEncryptFileName, CFile::modeCreate | CFile::modeWrite, &e ))
    {
        printf("%s could not be created %d/n", pchEncryptFileName, e.m_cause);
        fileb4.Close();
        return false;
    }

    BYTE    bBuffer[8];
    BYTE    bEncryptFileHead[8];
    UINT    uFileLen = fileb4.GetLength();

    memcpy(bEncryptFileHead,     "ISDN",    4);
    memcpy(bEncryptFileHead + 4, &uFileLen, 4);

    encryptfile.Write(bEncryptFileHead, 8);

    DWORD    dwRead;
    UINT    uPlainData[2];
    UINT    uCryptoData[2];
    do
    {
        memset(bBuffer, 0, 8);
        dwRead = fileb4.Read(bBuffer, 8);
        if ( dwRead > 0 && dwRead <= 8 )
        {
            memcpy(&uPlainData[0], bBuffer    , 4);
            memcpy(&uPlainData[1], bBuffer + 4, 4);
           
            encrypt(uPlainData, uCryptoData);         

            encryptfile.Write(&uCryptoData[0], 4);
            encryptfile.Write(&uCryptoData[1], 4);
        }
        //else if ( 8 > dwRead && 1 <= dwRead )
        //{
        //   
        //}       
    }
    while (dwRead > 0);

    // Close both files

    encryptfile.Close();
    fileb4.Close();

    try
    {
        CFile::Remove(pchFileName);
        try
        {
            CFile::Rename( pchEncryptFileName, pchFileName );
        }
        catch(CFileException* pExRename )
        {
            printf( "File %s not found %d/n", pchEncryptFileName, pExRename->m_cause);
            pExRename->Delete();
        }
    }
    catch (CFileException* pExRemove)
    {
        printf( "File %s cannot be removed/n", pchFileName);
        pExRemove->Delete();
    }   

    return true;
}
//文件解密函數
bool DecryptFile(char *pchFileName, unsigned int uiOffset, void *pMem, unsigned int &uiMemSize)
{
    CFile    fileb4;
    CFile    decryptfile;
    CFileException e;
    char    pchDecryptFileName[100];
    sprintf(pchDecryptFileName, "$%s", pchFileName);

    if( !fileb4.Open( pchFileName, CFile::modeRead | CFile::shareDenyNone, &e ) )
    {
        printf("%s could not be opened %d/n", pchFileName, e.m_cause);
        return false;
    }
    if ( !decryptfile.Open( pchDecryptFileName, CFile::modeCreate | CFile::modeWrite, &e ))
    {
        printf("%s could not be created %d/n", pchDecryptFileName, e.m_cause);
        fileb4.Close();
        return false;
    }

    UINT    uFileLen = fileb4.GetLength();
    if ( uFileLen % 8 != 0 )
    {
        printf("%s 's length mod 8 is not 0/n", pchFileName);
       
        decryptfile.Close();
        fileb4.Close();

        return false;
    }

    DWORD    dwRead;
    BYTE    bEncryptFileHead[8];
    UINT    uDecryptFileLen;
   
    dwRead = fileb4.Read(bEncryptFileHead, 8);
    if ( 8 == dwRead )
    {
        if ( bEncryptFileHead[0] != 'I' )
        {
            decryptfile.Close();
            fileb4.Close();
            return false;
        }
        if ( bEncryptFileHead[1] != 'S' )
        {
            decryptfile.Close();
            fileb4.Close();
            return false;
        }
        if ( bEncryptFileHead[2] != 'D' )
        {
            decryptfile.Close();
            fileb4.Close();
            return false;
        }
        if ( bEncryptFileHead[3] != 'N' )
        {
            decryptfile.Close();
            fileb4.Close();
            return false;
        }
        memcpy(&uDecryptFileLen, bEncryptFileHead + 4, 4 );
        if ( uDecryptFileLen + 8 > uFileLen || uDecryptFileLen + 16 < uFileLen )
        {
            decryptfile.Close();
            fileb4.Close();
            return false;
        }
    }
    else
    {
        decryptfile.Close();
        fileb4.Close();
        return false;
    }
   
    fileb4.Seek( uiOffset, CFile::current);   
   
    BYTE    bBuffer[8];
    UINT    uPlainData[2];
    UINT    uCryptoData[2];
    UINT    uDecryptFileLenHasWrite = 0;
    do
    {
        memset(bBuffer, 0, 8);
        dwRead = fileb4.Read(bBuffer, 8);
        if ( dwRead > 0 && dwRead <= 8 )
        {
            memcpy(&uCryptoData[0], bBuffer    , 4);
            memcpy(&uCryptoData[1], bBuffer + 4, 4);
           
            decrypt(uCryptoData,uPlainData);
           
            if ( uDecryptFileLen - uDecryptFileLenHasWrite >= 8 )
            {
                decryptfile.Write(&uPlainData[0], 4);
                decryptfile.Write(&uPlainData[1], 4);
           
                uDecryptFileLenHasWrite += 8;
            }
            else if ( uDecryptFileLen - uDecryptFileLenHasWrite >= 4 )
            {
                decryptfile.Write(&uPlainData[0], 4);

                uDecryptFileLenHasWrite += 4;

                decryptfile.Write(&uPlainData[1], uDecryptFileLen - uDecryptFileLenHasWrite);
               
                uDecryptFileLenHasWrite = uDecryptFileLen;
            }
            else
            {
                decryptfile.Write(&uPlainData[0], uDecryptFileLen - uDecryptFileLenHasWrite);

                uDecryptFileLenHasWrite = uDecryptFileLen;
            }
        }
        //else if ( 8 > dwRead && 1 <= dwRead )
        //{
        //   
        //}       
    }
    while (dwRead > 0);

    // Close both files

    decryptfile.Close();
    fileb4.Close();

    return true;
}
//主函數
void main()
{   
    if (sizeof(UINT)!=4)
    {
        printf("RC5 error: UINT has %d bytes./n",sizeof(UINT));
    }
   
    UINT j;
    char *keystr = "0123456789ABCDEF";
    for (j=0; j < KEYSIZE; j++)
    {
        SetKey((unsigned char)keystr[j]);
    }
   
    /* Setup, encrypt, and decrypt */
    setup();

    ////////////////////////////////////////////////////////////////////////
    //
    EncryptFile("Test.dat");
    UINT    uMemLen;
    DecryptFile("Test.dat", 0, NULL, uMemLen);
   
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章