Thread: Encryption program

  1. #1
    Registered User
    Join Date
    Jun 2005
    Posts
    1

    Encryption program

    Hi, I am a newbie in c programming and have e following doubts in an encryption program that I am doing.

    it is wif reference to msdk platform..there is a program attached that encrypts e file but as i am doing it for rcs and 3desdo i need to include it in e program so tat it will b able 2 run through e algo or it is already encrypted using the cryptapi?

    if they are included in the program, what is e syntax to include it? is it to include it as a method or a separate class?
    thanx =)

    Code:
     
    #include <stdio.h>
    #include <string.h>
    #include <conio.h>
    #include <windows.h>
    #include <wincrypt.h>
    #define MY_ENCODING_TYPE  (PKCS_7_ENCODING | X509v3_ENCODING)
    #define KEYLENGTH  0x00800000
    void MyHandleError(char *s);
    void GetConsoleInput(char* strInput, int intMaxChars);
    
    //-------------------------------------------------------------------
    // Copyright (c) Microsoft Corporation.  All rights reserved.
    // The following additional #define statements are required.
    #define ENCRYPT_ALGORITHM CALG_RC4 
    #define ENCRYPT_BLOCK_SIZE 8 
    
    // Declare the function EncryptFile. The function definition
    // follows main.
    
    BOOL EncryptFile(
         PCHAR szSource, 
         PCHAR szDestination, 
         PCHAR szPassword); 
     
    //-------------------------------------------------------------------
    // Begin main.
    
    void main(void) 
    { 
        PCHAR szSource; 
        PCHAR szDestination; 
        CHAR szPassword[100] = ""; 
        char  response;
     
    if(!(szSource=(char *)malloc(100)))
        MyHandleError("Memory allocation failed.");
    if(!(szDestination=(char *)malloc(100)))
        MyHandleError("Memory allocation failed.");
    
    printf("Encrypt a file. \n\n");
    printf("Enter the name of the file to be encrypted: ");
    fgets(szSource, 100, stdin);
    if(szSource[strlen(szSource)-1] == '\n')
         szSource[strlen(szSource)-1] = '\0';
    printf("Enter the name of the output file: ");
    fgets(szDestination, 100, stdin);
    if(szDestination[strlen(szDestination)-1] == '\n')
         szDestination[strlen(szDestination)-1] = '\0';
    printf("Use a password to encrypt this file? ( y/n ) ");
    response = getchar();
    if(response == 'y')
    {
        printf("Enter the password:");
        GetConsoleInput(szPassword, sizeof(szPassword)/sizeof(char) - 1);
    }
    else
    {
        printf("The key will be generated without using a password. \n");
    }
    
    //-------------------------------------------------------------------
    // Call EncryptFile to do the actual encryption.
     
    if(EncryptFile(szSource, szDestination, szPassword))
    {
           printf("Encryption of the file %s was a success. \n", 
    		   szSource);
           printf("The encrypted data is in file %s.\n",szDestination);
    }
    else
    {
          MyHandleError("Error encrypting file!"); 
    }
    //-------------------------------------------------------------------
    // Free memory.
    if(szSource)
         free(szSource);
    if(szDestination)
         free(szDestination);
    
    } // end main
     
    //-------------------------------------------------------------------
    // Code for the function EncryptFile called by main.
    
    static BOOL EncryptFile(
            PCHAR szSource, 
            PCHAR szDestination, 
            PCHAR szPassword)
    //-------------------------------------------------------------------
    // Parameters passed are:
    //  szSource, the name of the input, a plaintext file.
    //  szDestination, the name of the output, an encrypted file to be 
    //   created.
    //  szPassword, either NULL if a password is not to be used or the 
    //   string that is the password.
    { 
    //-------------------------------------------------------------------
    // Declare and initialize local variables.
    
    FILE *hSource; 
    FILE *hDestination; 
    
    HCRYPTPROV hCryptProv; 
    HCRYPTKEY hKey; 
    HCRYPTKEY hXchgKey; 
    HCRYPTHASH hHash; 
    
    PBYTE pbKeyBlob; 
    DWORD dwKeyBlobLen; 
    
    PBYTE pbBuffer; 
    DWORD dwBlockLen; 
    DWORD dwBufferLen; 
    DWORD dwCount; 
     
    //-------------------------------------------------------------------
    // Open source file. 
    
    if(hSource = fopen(szSource,"rb"))
    {
       printf("The source plaintext file, %s, is open. \n", szSource);
    }
    else
    { 
       MyHandleError("Error opening source plaintext file!");
    } 
    //-------------------------------------------------------------------
    // Open destination file. 
    
    if(hDestination = fopen(szDestination,"wb"))
    {
         printf("Destination file %s is open. \n", szDestination);
    }
    else
    {
        MyHandleError("Error opening destination ciphertext file!"); 
    }
    // Get the handle to the default provider. 
    if(CryptAcquireContext(
          &hCryptProv, 
          NULL, 
          MS_ENHANCED_PROV, 
          PROV_RSA_FULL, 
          0))
    {
       printf("A cryptographic provider has been acquired. \n");
    }
    else
    {
       MyHandleError("Error during CryptAcquireContext!"); 
    }
    //-------------------------------------------------------------------
    // Create the session key.
    
    if(!szPassword ) 
    { 
         //--------------------------------------------------------------
         // No password was passed.
         // Encrypt the file with a random session key, and write the key
         // to a file. 
         
         //--------------------------------------------------------------
         // Create a random session key. 
    
         if(CryptGenKey(
              hCryptProv, 
              ENCRYPT_ALGORITHM, 
              KEYLENGTH | CRYPT_EXPORTABLE, 
              &hKey))
          {
              printf("A session key has been created. \n");
          } 
          else
          {
              MyHandleError("Error during CryptGenKey. \n"); 
          }
         //--------------------------------------------------------------
         // Get the handle to the encrypter's exchange public key. 
    
         if(CryptGetUserKey(
               hCryptProv, 
               AT_KEYEXCHANGE, 
               &hXchgKey))
          {
                printf("The user public key has been retrieved. \n");
           }
           else
           { 
                 MyHandleError("User public key is not available \
                    and may not exist."); 
           }
         //--------------------------------------------------------------
         // Determine size of the key BLOB, and allocate memory. 
    
         if(CryptExportKey(
               hKey, 
               hXchgKey, 
               SIMPLEBLOB, 
               0, 
               NULL, 
               &dwKeyBlobLen))
          {
               printf("The key BLOB is %d bytes long. \n",dwKeyBlobLen);
           }
           else
           {  
                MyHandleError("Error computing BLOB length! \n");
           }
           if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))
           { 
              printf("Memory is allocated for the key BLOB. \n");
           }
           else
           { 
              MyHandleError("Out of memory. \n"); 
           }
         //--------------------------------------------------------------
         // Encrypt and export the session key into a simple key BLOB. 
         
         if(CryptExportKey(
              hKey, 
              hXchgKey, 
              SIMPLEBLOB, 
              0, 
              pbKeyBlob, 
              &dwKeyBlobLen))
           {
               printf("The key has been exported. \n");
           } 
           else
           {
               MyHandleError("Error during CryptExportKey!\n");
           } 
         //--------------------------------------------------------------
         // Release the key exchange key handle. 
    
         if(hXchgKey)
         {
              if(!(CryptDestroyKey(hXchgKey)))
                   MyHandleError("Error during CryptDestroyKey"); 
      
              hXchgKey = 0;
         }
     
         //--------------------------------------------------------------
         // Write the size of the key BLOB to a destination file. 
    
         fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination); 
         if(ferror(hDestination))
         { 
             MyHandleError("Error writing header.");
         }
         else
         {
             printf("A file header has been written. \n");
         }
         //--------------------------------------------------------------
         // Write the key BLOB to a destination file. 
         
         fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination); 
         if(ferror(hDestination))
         { 
            MyHandleError("Error writing header");
         }
         else
         {
            printf("The key BLOB has been written to the file. \n");
         }
         // Free memory.
         free(pbKeyBlob);
    } 
    else 
    { 
    //-------------------------------------------------------------------
    // The file will be encrypted with a session key derived from a
    // password.
    // The session key will be recreated when the file is decrypted
    // only if the password used to create the key is available. 
    
    //-------------------------------------------------------------------
    // Create a hash object. 
    
    if(CryptCreateHash(
           hCryptProv, 
           CALG_MD5, 
           0, 
           0, 
           &hHash))
        {
            printf("A hash object has been created. \n");
        }
        else
        { 
             MyHandleError("Error during CryptCreateHash!\n");
        }  
    //-------------------------------------------------------------------
    // Hash the password. 
    
    if(CryptHashData(
           hHash, 
           (BYTE *)szPassword, 
           strlen(szPassword), 
           0))
     {
        printf("The password has been added to the hash. \n");
     }
     else
     {
        MyHandleError("Error during CryptHashData. \n"); 
     }
    //-------------------------------------------------------------------
    // Derive a session key from the hash object. 
    
    if(CryptDeriveKey(
           hCryptProv, 
           ENCRYPT_ALGORITHM, 
           hHash, 
           KEYLENGTH, 
           &hKey))
     {
       printf("An encryption key is derived from the password hash. \n"); 
     }
     else
     {
       MyHandleError("Error during CryptDeriveKey!\n"); 
     }
    //-------------------------------------------------------------------
    // Destroy hash object. 
    
    if(hHash) 
    {
        if(!(CryptDestroyHash(hHash)))
           MyHandleError("Error during CryptDestroyHash"); 
        hHash = 0;
    }
    } 
    //-------------------------------------------------------------------
    // The session key is now ready. If it is not a key derived from a 
    // password, the session key encrypted with the encrypter's private 
    // key has been written to the destination file.
     
    //-------------------------------------------------------------------
    // Determine the number of bytes to encrypt at a time. 
    // This must be a multiple of ENCRYPT_BLOCK_SIZE.
    // ENCRYPT_BLOCK_SIZE is set by a #define statement.
    
    dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; 
    
    //-------------------------------------------------------------------
    // Determine the block size. If a block cipher is used, 
    // it must have room for an extra block. 
    
    if(ENCRYPT_BLOCK_SIZE > 1) 
        dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; 
    else 
        dwBufferLen = dwBlockLen; 
        
    //-------------------------------------------------------------------
    // Allocate memory. 
    if(pbBuffer = (BYTE *)malloc(dwBufferLen))
    {
        printf("Memory has been allocated for the buffer. \n");
    }
    else
    { 
        MyHandleError("Out of memory. \n"); 
    }
    //-------------------------------------------------------------------
    // In a do loop, encrypt the source file, 
    // and write to the source file. 
    
    do 
    { 
    
    //-------------------------------------------------------------------
    // Read up to dwBlockLen bytes from the source file. 
    dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); 
    if(ferror(hSource))
    { 
        MyHandleError("Error reading plaintext!\n");
    }
     
    //-------------------------------------------------------------------
    // Encrypt data. 
    if(!CryptEncrypt(
         hKey, 
         0, 
         feof(hSource), 
         0, 
         pbBuffer, 
         &dwCount, 
         dwBufferLen))
    { 
       MyHandleError("Error during CryptEncrypt. \n"); 
    } 
    
    //-------------------------------------------------------------------
    // Write data to the destination file. 
    
    fwrite(pbBuffer, 1, dwCount, hDestination); 
    if(ferror(hDestination))
    { 
        MyHandleError("Error writing ciphertext.");
    }
    
    } 
    while(!feof(hSource)); 
    //-------------------------------------------------------------------
    // End the do loop when the last block of the source file has been
    // read, encrypted, and written to the destination file.
    
    //-------------------------------------------------------------------
    // Close files.
    
    if(hSource)
    {
        if(fclose(hSource))
            MyHandleError("Error closing source file");
    }
    if(hDestination)
    {
        if(fclose(hDestination))
            MyHandleError("Error closing destination file");
    }
    
    //-------------------------------------------------------------------
    // Free memory. 
    
    if(pbBuffer) 
         free(pbBuffer); 
     
    //-------------------------------------------------------------------
    // Destroy the session key. 
    
    if(hKey)
    {
        if(!(CryptDestroyKey(hKey)))
            MyHandleError("Error during CryptDestroyKey");
    }
    
    //-------------------------------------------------------------------
    // Release the provider handle. 
    
    if(hCryptProv)
    {
        if(!(CryptReleaseContext(hCryptProv, 0)))
            MyHandleError("Error during CryptReleaseContext");
    }
    return(TRUE); 
    } // end Encryptfile
    
    //-------------------------------------------------------------------
    // This example uses the function MyHandleError, a simple error
    // handling function to print an error message to the standard error 
    // (stderr) file and exit the program. 
    // For most applications, replace this function with one 
    // that does more extensive error reporting.
    
    void MyHandleError(char *s)
    {
        fprintf(stderr,"An error occurred in running the program. \n");
        fprintf(stderr,"%s\n",s);
        fprintf(stderr, "Error number %x.\n", GetLastError());
        fprintf(stderr, "Program terminating. \n");
        exit(1);
    } // end MyHandleError
    
    //-------------------------------------------------------------------
    // The GetConsoleInput function gets an array of characters from the 
    // keyboard, while printing only asterisks to the screen.
    
    void GetConsoleInput(char* strInput, 
                         int intMaxChars)
    {
        char ch;
        char minChar = ' ';
        minChar++;
    
        ch = getch();
        while (ch != '\r')
        {
            if (ch == '\b' && strlen(strInput) > 0)
            {
                strInput[strlen(strInput)-1]   = '\0';
                printf("\b \b");
            }
            else if (ch >= minChar && strlen(strInput) < intMaxChars)
            {
                strInput[strlen(strInput)+1] = '\0';
                strInput[strlen(strInput)]   = ch;
                putch('*');
            }
            ch = getch();
        }
        putch('\n');
    }

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Well I'm not sure exactly what your question is, but you have a number of issues:

    1) This is wrong. Read the FAQ:
    Code:
    void main(void)
    2) You don't ever need to typecast the return value of malloc. This is in the FAQ also.
    Code:
    if(!(szSource=(char *)malloc(100)))
    It would be:
    Code:
    if( !(szSource = malloc( 100 )) )
    3) Also, if PCHAR is not the same size as char, then this malloc is wrong. It should be:
    Code:
    if( !(szSource = malloc( sizeof( PCHAR ) * 100 )) )
    These are wrong too, for the same reasons:
    Code:
    if(!(szDestination=(char *)malloc(100)))
    And here:
    Code:
    if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))
    Here too:
    Code:
    if(pbBuffer = (BYTE *)malloc(dwBufferLen))
    4) This could be written better:
    Code:
        CHAR szPassword[100] = ""; 
        ...
        GetConsoleInput(szPassword, sizeof(szPassword)/sizeof(char) - 1);
    Consider something like this:
    Code:
    #define PASSWORDLENGTH 100
        CHAR szPassword[ PASSWORDLENGTH ] = { 0 };
        GetConsoleInput(szPassword, PASSWORDLENGTH - 1);
    5) Since your call to main is incorrect, be sure and correct it, and return an appropriate value:
    Code:
    } // end main
    6) This check, while it may seem to be correct, is actually wrong:
    Code:
    if(hSource = fopen(szSource,"rb"))
    It should be:
    Code:
    if( (hSource = fopen( szSource, "rb")) )
    The truth test without the set of parenthesis is just to see if the assignment actually assigned something, which it always will.

    Same thing here:
    Code:
    if(hDestination = fopen(szDestination,"wb"))
    7) "szPassword" is always going to be true. This test will always evaluate to false:
    Code:
    if(!szPassword )
    "szPassword" is always pointing to something. It's pointing to the array you pass to the function. Therefore, this test will always be pointing at something. It will never be null, because you always pass a pointer, even if the array, in this case, doesn't have anything in the array itself.


    8) Why not test the return value of your functions?
    Code:
         fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination); 
         ...
         fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);
    9) Unless you're compiling as C++, these should be set to NULL, not 0:
    Code:
    hXchgKey = 0;
    ...
    hHash = 0;
    10) Your indenting is horrible in places, but that aside, you shouldn't do this:
    Code:
    while(!feof(hSource));
    It's in the FAQ also. You shouldn't use feof to control loops.


    11) You only ever return TRUE in this function, so why bother returning anything at all?
    Code:
    return(TRUE);

    12) The only gripe I have here, is that you call it many times without:
    a) closing open files
    b) freeing allocated memory
    It's possible your OS will do all of this for you, but it's not required in any way shape or form. So this could lead to memory leaks, running out of file handles, etc.


    13) I don't think this is really what you want, but I could be wrong:
    Code:
        char minChar = ' ';
        minChar++;
    You're saying "set 'minChar' to the character that follows the space in the ASCII set. Is this really what you want? If so, since you never change 'minChar' any other time, why don't you just set it to that in the first place?
    Code:
    char minChar = ' ' + 1;
    As to your origional question, again, I'm not clear on what you're asking.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Encryption Program (help me please)
    By Arkanos in forum Windows Programming
    Replies: 7
    Last Post: 10-30-2005, 08:01 PM
  2. I need some help with my program please.
    By agentxx04 in forum C Programming
    Replies: 9
    Last Post: 09-26-2004, 07:51 AM
  3. Basic encryption program???
    By Finchie_88 in forum C++ Programming
    Replies: 14
    Last Post: 09-10-2004, 09:01 AM
  4. Replies: 2
    Last Post: 05-10-2002, 04:16 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM