home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / crypto / encrypt / encrypt.c < prev    next >
C/C++ Source or Header  |  1997-10-10  |  7KB  |  242 lines

  1. /******************************************************************************\
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright 1996-1997 Microsoft Corporation.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. \******************************************************************************/
  10.  
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <wincrypt.h>
  15.  
  16. #ifdef USE_BLOCK_CIPHER
  17.     // defines for RC2 block cipher
  18.     #define ENCRYPT_ALGORITHM    CALG_RC2
  19.     #define ENCRYPT_BLOCK_SIZE    8
  20. #else
  21.     // defines for RC4 stream cipher
  22.     #define ENCRYPT_ALGORITHM    CALG_RC4
  23.     #define ENCRYPT_BLOCK_SIZE    1
  24. #endif
  25.  
  26. static BOOL CAPIEncryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword);
  27.  
  28. /*****************************************************************************/
  29. void _cdecl main(int argc, char *argv[])
  30. {
  31.     PCHAR szSource    = NULL;
  32.     PCHAR szDestination = NULL;
  33.     PCHAR szPassword    = NULL;
  34.  
  35.     // Validate argument count.
  36.     if(argc != 3 && argc != 4) {
  37.     printf("USAGE: encrypt <source file> <dest file> [ <password> ]\n");
  38.     exit(1);
  39.     }
  40.  
  41.     // Parse arguments.
  42.     szSource       = argv[1];
  43.     szDestination  = argv[2];
  44.     if(argc == 4) {
  45.     szPassword = argv[3];
  46.     }
  47.  
  48.     if(!CAPIEncryptFile(szSource, szDestination, szPassword)) {
  49.     printf("Error encrypting file!\n");
  50.     exit(1);
  51.     }
  52.  
  53.     exit(0);
  54. }
  55.  
  56. /*****************************************************************************/
  57. static BOOL CAPIEncryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword)
  58. {
  59.     FILE *hSource      = NULL;
  60.     FILE *hDestination = NULL;
  61.     INT eof = 0;
  62.  
  63.     HCRYPTPROV hProv   = 0;
  64.     HCRYPTKEY hKey     = 0;
  65.     HCRYPTKEY hXchgKey = 0;
  66.     HCRYPTHASH hHash   = 0;
  67.  
  68.     PBYTE pbKeyBlob = NULL;
  69.     DWORD dwKeyBlobLen;
  70.  
  71.     PBYTE pbBuffer = NULL;
  72.     DWORD dwBlockLen;
  73.     DWORD dwBufferLen;
  74.     DWORD dwCount;
  75.  
  76.     BOOL status = FALSE;
  77.  
  78.     // Open source file.
  79.     if((hSource = fopen(szSource,"rb")) == NULL) {
  80.     printf("Error opening Plaintext file!\n");
  81.         goto done;
  82.     }
  83.  
  84.     // Open destination file.
  85.     if((hDestination = fopen(szDestination,"wb")) == NULL) {
  86.     printf("Error opening Ciphertext file!\n");
  87.         goto done;
  88.     }
  89.  
  90.     // Get handle to the default provider.
  91.     if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
  92.         printf("Error %x during CryptAcquireContext!\n", GetLastError());
  93.         goto done;
  94.     }
  95.  
  96.     if(szPassword == NULL) {
  97.     // Encrypt the file with a random session key.
  98.  
  99.     // Create a random session key.
  100.     if(!CryptGenKey(hProv, ENCRYPT_ALGORITHM, CRYPT_EXPORTABLE, &hKey)) {
  101.         printf("Error %x during CryptGenKey!\n", GetLastError());
  102.         goto done;
  103.     }
  104.  
  105.     // Get handle to key exchange public key.
  106.     if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey)) {
  107.         printf("Error %x during CryptGetUserKey!\n", GetLastError());
  108.         goto done;
  109.     }
  110.  
  111.     // Determine size of the key blob and allocate memory.
  112.     if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, NULL, &dwKeyBlobLen)) {
  113.         printf("Error %x computing blob length!\n", GetLastError());
  114.         goto done;
  115.     }
  116.     if((pbKeyBlob = malloc(dwKeyBlobLen)) == NULL) {
  117.         printf("Out of memory!\n");
  118.         goto done;
  119.     }
  120.  
  121.     // Export session key into a simple key blob.
  122.     if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwKeyBlobLen)) {
  123.         printf("Error %x during CryptExportKey!\n", GetLastError());
  124.         goto done;
  125.     }
  126.  
  127.     // Release key exchange key handle.
  128.     CryptDestroyKey(hXchgKey);
  129.     hXchgKey = 0;
  130.  
  131.     // Write size of key blob to destination file.
  132.     fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);
  133.     if(ferror(hDestination)) {
  134.         printf("Error writing header!\n");
  135.         goto done;
  136.     }
  137.  
  138.     // Write key blob to destination file.
  139.     fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);
  140.     if(ferror(hDestination)) {
  141.         printf("Error writing header!\n");
  142.         goto done;
  143.     }
  144.  
  145.     } else {
  146.     // Encrypt the file with a session key derived from a password.
  147.  
  148.     // Create a hash object.
  149.     if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
  150.         printf("Error %x during CryptCreateHash!\n", GetLastError());
  151.         goto done;
  152.     }
  153.  
  154.     // Hash in the password data.
  155.     if(!CryptHashData(hHash, szPassword, strlen(szPassword), 0)) {
  156.         printf("Error %x during CryptHashData!\n", GetLastError());
  157.         goto done;
  158.     }
  159.  
  160.     // Derive a session key from the hash object.
  161.     if(!CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey)) {
  162.         printf("Error %x during CryptDeriveKey!\n", GetLastError());
  163.         goto done;
  164.     }
  165.  
  166.     // Destroy the hash object.
  167.     CryptDestroyHash(hHash);
  168.     hHash = 0;
  169.     }
  170.  
  171.     // Determine number of bytes to encrypt at a time. This must be a multiple
  172.     // of ENCRYPT_BLOCK_SIZE.
  173.     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
  174.  
  175.     // Determine the block size. If a block cipher is used this must have
  176.     // room for an extra block.
  177.     if(ENCRYPT_BLOCK_SIZE > 1) {
  178.     dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
  179.     } else {
  180.     dwBufferLen = dwBlockLen;
  181.     }
  182.  
  183.     // Allocate memory.
  184.     if((pbBuffer = malloc(dwBufferLen)) == NULL) {
  185.     printf("Out of memory!\n");
  186.     goto done;
  187.     }
  188.  
  189.     // Encrypt source file and write to Source file.
  190.     do {
  191.     // Read up to 'dwBlockLen' bytes from source file.
  192.     dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
  193.     if(ferror(hSource)) {
  194.         printf("Error reading Plaintext!\n");
  195.             goto done;
  196.         }
  197.     eof = feof(hSource);
  198.  
  199.         // Encrypt data
  200.     if(!CryptEncrypt(hKey, 0, eof, 0, pbBuffer, &dwCount, dwBufferLen)) {
  201.             printf("bytes required:%d\n",dwCount);
  202.             printf("Error %x during CryptEncrypt!\n", GetLastError());
  203.             goto done;
  204.         }
  205.  
  206.     // Write data to destination file.
  207.     fwrite(pbBuffer, 1, dwCount, hDestination);
  208.     if(ferror(hDestination)) {
  209.         printf("Error writing Ciphertext!\n");
  210.             goto done;
  211.         }
  212.     } while(!feof(hSource));
  213.  
  214.     status = TRUE;
  215.  
  216.     printf("OK\n");
  217.  
  218.     done:
  219.  
  220.     // Close files.
  221.     if(hSource) fclose(hSource);
  222.     if(hDestination) fclose(hDestination);
  223.  
  224.     // Free memory.
  225.     if(pbKeyBlob) free(pbKeyBlob);
  226.     if(pbBuffer) free(pbBuffer);
  227.  
  228.     // Destroy session key.
  229.     if(hKey) CryptDestroyKey(hKey);
  230.  
  231.     // Release key exchange key handle.
  232.     if(hXchgKey) CryptDestroyKey(hXchgKey);
  233.  
  234.     // Destroy hash object.
  235.     if(hHash) CryptDestroyHash(hHash);
  236.  
  237.     // Release provider handle.
  238.     if(hProv) CryptReleaseContext(hProv, 0);
  239.  
  240.     return(status);
  241. }
  242.