1 2 3 4 5 6 7 | #include #include // this header is necessary for wincrypt.h #include #define ENCRYPT_ALGORITHM CALG_RC4 // we are using RC4 algorithm #define KEYLENGTH 0x00800000 #define ENCRYPT_BLOCK_SIZE 8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | HCRYPTPROV GetCryptContainer(LPCSTR keyContainer) { HCRYPTPROV hCryptProv = NULL; if(CryptAcquireContext( &hCryptProv, keyContainer, NULL, PROV_RSA_FULL, 0)) { printf("A cryptographic provider has been acquired.\n"); } else { if (GetLastError() == NTE_BAD_KEYSET) { if(CryptAcquireContext( &hCryptProv, keyContainer, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { printf("A new key container has been created.\n"); } else { printf("Could not create a new key container.\n"); } } else { printf("A cryptographic service handle could not be acquired.\n"); } } return hCryptProv; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | HCRYPTHASH CreateHashObj(HCRYPTPROV hCryptProv, const char * szPassword) { HCRYPTHASH hHash = NULL; if(CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash)) { printf("A hash object has been created. \n"); // hash the password if(CryptHashData( hHash, (BYTE *)szPassword, strlen(szPassword), 0)) { printf("The password has been added to the hash. \n"); } else { // reset hash object to NULL CryptDestroyHash(hHash); hHash = NULL; } } else { printf("Failed to create hash object.\n"); } return hHash; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | HCRYPTKEY GetDeriveKey(HCRYPTPROV hCryptProv, HCRYPTHASH hHash) { HCRYPTKEY hKey = NULL; 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"); } return hKey; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | int _tmain(int argc, char* argv[]) { HCRYPTPROV hCryptProv = NULL; // handle for a cryptographic // provider context. HCRYPTHASH hHash = NULL; // handle for hash object LPCSTR keyContainer = "MyKeyContainer"; // name of the key container // to be used. char szPassword[10] = "12345"; // password for encryption and // decryption HCRYPTKEY hKey; // handle for session key PBYTE pbBuffer; // hold the data being encrypt // or decrypt DWORD dwCount; // data length // make sure that we have enough argument to do the demo. // otherwise exit the program if(argc < 2) { printf("Usage: CryptoConsole.exe [data]"); exit(1); } // get CSP hCryptProv = GetCryptContainer(keyContainer); if(!hCryptProv) exit(1); // exit if failed to get CSP // get the hash object hHash = CreateHashObj(hCryptProv, szPassword); if(!hHash) exit(1); // exit if failed to get hash object // get the session key hKey = GetDeriveKey(hCryptProv, hHash); if(!hKey) exit(1); // exit if failed to get session key // determine input data length int len = strlen(argv[1]); // Determine the block size. If a block cipher is used, // it must have room for an extra block. DWORD dwBufferLen = len + ENCRYPT_BLOCK_SIZE - (len % ENCRYPT_BLOCK_SIZE); // Allocate memory if(pbBuffer = (BYTE *)malloc(dwBufferLen)) { printf("Memory has been allocated for the buffer. \n"); } else { printf("Failed to allocate memory for the buffer. \n"); exit(1); } // copy the data value to buffer memcpy(pbBuffer, argv[1], dwBufferLen); printf("++++++++++++++++++++++++++++++++\n"); printf("Before encryption: %s\n", argv[1]); dwCount = strlen(argv[1]); // encrypt data if(!CryptEncrypt( hKey, 0, TRUE, 0, pbBuffer, &dwCount, dwBufferLen)) { printf("Error during CryptEncrypt. \n"); } else { printf("After encryption: %s\n", pbBuffer); unsigned char *pDecrypt = pbBuffer; DWORD delen = _mbslen(pbBuffer); // decrypt data if(CryptDecrypt( hKey, 0, TRUE, 0, pbBuffer, &delen)) { printf("After decryption: %s\n", pbBuffer); printf("++++++++++++++++++++++++++++++++\n"); } } // Remove all references if(pbBuffer) free(pbBuffer); if(hKey) CryptDestroyKey(hKey); if(hHash) CryptDestroyHash(hHash); if(hCryptProv) CryptReleaseContext(hCryptProv,0); return 0; } |

I use this example code to encrypt some data(names,adresses,#s.s.,etc.) and I copied the encrypted data in a file. Then I used the code with some modifications to decrypt the encrypted data in the file. It seemed to work but with some data it didnt work. For example it can decrypt only the first two number of a social security or the first three letters of a name etc. If I change the password it encrypt/decrypt some data well but some not. Sorry for my bad english but if someone can help me I am going to appreciate it.
Mind to share what kind of data that you’re going to encrypt & decrypt so that i can try to figure out why it cannot be encrypted & decrypted well?
I get data from edit controls, such as name, social security number, etc., and store it in char string variables. Then I send the value of this variables to a function I called Encrypt(here I use your code with some minor changes) to encrypt the data. I copy the encrypted data to a text file using basic i/o streams. Then i read the text file containing the encrypted data (using i/o streams again) and store it in other char string variables. I send the value of this variables to a function i called Decrypt (here I use your code again with minor modifications) to decrypt the data. Finally, using SetDlgItemText() I put the decrypted data in edit controls again.
The problem is my code decrypts some names and some not, some social security numbers and some not, etc. When I use your code exactly as it is, it works perfect but the problem is that your code encrypts and decrypt inmediately and I need to encrypt, save the encrypted data in a file, to in the future decrypt it and use it.
I think the problem is that sometimes the derived key used for decrypt the data isnt exactly the same used to encrypt the data. But I used the same password so it is supposed to work. Other thought I had was a problem managing the memory or data lenght.
It seem like MS’s CryptoApi doesn’t encrypt accordingly with certain text or keyword. I managed to reproduce this now. 🙂
Any idea how to solve that? I am creating a client data base. The information I have to manage is confidential so I want it to be encrypted. I want to have access to it only with my program, wich of course is password protected.
when you write the ciphertext to the file, do u use the length of the ciphertext or the original plaintext? The issue that you are facing now could be truncated problem.
I’ve created a solution on how to store the ciphertext into a text file. You may refer this at the following post Storing encrypted data into text file
Thank You so much for your help. Your code really help me in what I’m trying to do and I learned a lot.