Crypt(API) any data WITHOUT password
Click here for larger image
Environment: VC6 NT5 SP2
By default the NT4+ offers to you CryptoAPI. This is a set of complex functions for crypting, decrypting, hashing, signing and so on. Sometimes you need want two functions such as Crypt() and Decrypt() to work with the data. Here you'll find them! A password isn't required because you enter it in the login procedure. Only the current logged user can decrypt crypted data. This is pretty useful for the user since there is no need to remember a NEW password!
Updates:
Crypto API is based on CSP - this means Cryptographic Service Providers. The strenght of crypted data depends of CSP. The following table shows the differences between the Base Provider, and the Enhanced Provider. The key lengths shown are the default keylengths.
| Algorithm | Base Provider | Enhanced Provider |
|---|---|---|
| RSA public-key signature algorithm | Key length: 512 bits. | Key length: 1,024 bits. |
| RSA public-key exchange algorithm | Key length: 512 bits. | Key length: 1,024 bits. |
| RC2 block encryption algorithm | Key length: 40 bits. | Key length: 128 bits. Salt length: settable. |
| RC4 stream encryption algorithm | Key length: 40 bits. | Key length: 128 bits. Salt length: settable. |
| DES | Not supported. | Key length: 56 bits. |
| Triple DES (2 key) | Not supported. | Key length: 112 bits. |
| Triple DES (3 key) | Not supported. | Key length: 168 bits. |
Crypted data has got almost the same size as source data (in brackets you can find size if you will use my functions to convert data to ASCII from BIN) :
119[B] -> 200 [B] (400[B]) 244[kB] -> 246[kB] (493[kB])
In the code below you can find also two functions to convert data from/to ASCII or binary. This can be useful to save the crypted data for example to INI files. At the end you can find simple example of usage (in the main() function)
This code is written for simplicity, so there aren't proper error handling mechanisms. You'll need to add that! I didn't tested the functions on NT4, only on Win2k (NT5); however, there shouldn't be any problems on NT4.
This code after compile you should link with advapi32.lib and user32.lib.
#define _CRYPT32_
#define _WIN32_WINNT 0x0500
#include "stdafx.h"
#include <stdio.h>
#include <objbase.h>
#include <wincrypt.h>
// decrypt buffer
//
// IN:
// pIn - pointer to memory to decrypt
// plSize - pointer to long which hold pIn size in bytes
//
// OUT:
// pIn - decrypted memory block
// plSize - size of decrypted memory
BOOL Decrypt(unsigned char *pIn, long *plSize)
{
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
DWORD dwCount;
BYTE *pbKeyBlob = NULL;
DWORD dwBlobLen;
// Get a handle to the default provider.
if (!CryptAcquireContext(&hProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
return FALSE;
// Read the key blob length from the source and
// init pointer
memcpy(&dwBlobLen, pIn, sizeof(DWORD));
pbKeyBlob = (BYTE *)&pIn[sizeof(DWORD)];
// Import the key blob into the CSP.
if (!CryptImportKey(hProv,
pbKeyBlob,
dwBlobLen,
0, 0,
&hKey))
return FALSE;
// decrypt all
dwCount =*plSize - (sizeof(DWORD)+dwBlobLen);
if (!CryptDecrypt(hKey,
0,
TRUE,
0,
&pIn[sizeof(DWORD)+dwBlobLen],
&dwCount))
return FALSE;
// inform user about the lenght of decrypted data
memmove(pIn, &pIn[sizeof(DWORD)+dwBlobLen], dwCount);
*plSize = dwCount;
// Destroy the session key.
if(hKey != 0) CryptDestroyKey(hKey);
// Release the provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);
return TRUE;
}
// crypt memory block via random key (generated every time)
// this key is also crypted and saved with the body BUT!
// you dont neede password! why?
// becouse you enter the password in login procedure!
// yes this function takes the logged user key to crypt.
//
// IN:
// pIn - buffer to crypt
// plSize - size of data to crypt (buffer)
//
// OUT:
// ppOut - pointer to pointer which will hold crypted
// data (bigger than data at in!)
// plSize - size of crypted data
BOOL Crypt(unsigned char *pIn,
long *plSize,
unsigned char **ppOut)
{
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTKEY hXchgKey = 0;
DWORD dwCount, dwNewBufLen;
BYTE *pbKeyBlob = NULL;
DWORD dwBlobLen;
// Get a handle to the default provider.
if(!CryptAcquireContext(&hProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
// Some sort of error occured, create default key container.
if (!CryptAcquireContext( &hProv,
NULL,
MS_DEF_PROV,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
// Error creating key container!
return FALSE;
// Get a handle to key exchange key.
if (!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey))
if (GetLastError()==NTE_NO_KEY)
{
// Create key exchange key pair.
if (!CryptGenKey(hProv,AT_KEYEXCHANGE,0,&hKey))
{
// Error during CryptGenKey!
CryptReleaseContext(hProv, 0);
return FALSE;
}
else
{
CryptDestroyKey(hKey);
CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey);
}
}
else
return FALSE;
// Create a random block cipher session key.
if (!CryptGenKey(hProv,
CALG_RC2,
CRYPT_EXPORTABLE,
&hKey))
return FALSE;
// Determine the size of the key blob and allocate memory.
if (!CryptExportKey( hKey,
hXchgKey,
SIMPLEBLOB,
0,
NULL,
&dwBlobLen))
return FALSE;
if ((pbKeyBlob =
(unsigned char *)malloc(dwBlobLen)) == NULL)
return FALSE;
// Export the key into a simple key blob.
if (!CryptExportKey(hKey,
hXchgKey,
SIMPLEBLOB,
0,
pbKeyBlob,
&dwBlobLen))
{
free(pbKeyBlob);
return FALSE;
}
// how much memory neede for ciphered block?
dwCount = *plSize;
if (!CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwCount, 0))
return FALSE;
// put on output the len, key blob, and alloc memory
*ppOut = (unsigned char *)malloc(sizeof(dwBlobLen) +
dwBlobLen + dwCount);
if (!*ppOut)
return FALSE;
memcpy(*ppOut, &dwBlobLen, sizeof(dwBlobLen));
memcpy(&(*ppOut)[sizeof(dwBlobLen)],
pbKeyBlob,
dwBlobLen);
// Free memory.
free(pbKeyBlob);
// finally crypt!
memcpy(&(*ppOut)[sizeof(dwBlobLen)+dwBlobLen], pIn, *plSize);
dwNewBufLen = dwCount;
dwCount = *plSize;
if (!CryptEncrypt(hKey,
0,
TRUE,
0,
&(*ppOut)[sizeof(dwBlobLen)+dwBlobLen],
&dwCount,
dwNewBufLen))
return FALSE;
// update output size
*plSize = sizeof(dwBlobLen) + dwBlobLen + dwCount;
// Destroy the session key.
if(hKey != 0) CryptDestroyKey(hKey);
// Destroy the key exchange key.
if(hXchgKey != 0) CryptDestroyKey(hXchgKey);
// Release the provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);
return TRUE;
}
// conver binary data to ASCII string
//
// IN:
// pIn - binary data
// lSize - size of those data
//
// OUT:
// ppOut - new allocated string with data
// (twice bigger than binary)
BOOL Bin2ASCII(unsigned char *pIn,
long lSize,
unsigned char **ppOut)
{
// alloc memory (lSize *2)
*ppOut = (unsigned char *)malloc((lSize*2)+1);
if (!*ppOut)
return FALSE;
for (long l=0; l<lSize; l++)
wsprintf((char *)&(*ppOut)[l*2], "%02X", pIn[l]);
return TRUE;
}
// convert ASCII string generated by Bin2ASCII() to binary data
//
// IN:
// pIn - string of data
// lSize - string len
//
// OUT:
// ppOut - binary data (twice smaller than string)
BOOL ASCII2Bin(unsigned char *pIn,
long lSize,
unsigned char **ppOut)
{
char szBuf[3];
// alloc memory (lSize/2) + one for zero at end
*ppOut = (unsigned char *)malloc((lSize/2)+1);
if (!*ppOut)
return FALSE;
szBuf[2] = NULL;
for (long l=0; l<lSize; l++)
{
szBuf[0] = pIn[l*2];
szBuf[1] = pIn[(l*2)+1];
(*ppOut)[l] = (unsigned char)strtoul(szBuf, NULL, 16);
}
return TRUE;
}
int main(int argc, char* argv[])
{
FILE *fIn, *fOut;
unsigned char Buf[1024], *pBuf, *pOut;
// decrypt the file
fIn = fopen("test1.xxx", "rb");
long l = fread(Buf, 1, sizeof(Buf), fIn);
ASCII2Bin(Buf, l, &pBuf);
l/=2;
Decrypt(pBuf, &l);
pBuf[l]=0;
fclose(fIn);
// encrypt file
fIn = fopen("test1.txt", "rb");
fOut = fopen("test1.xxx", "wb");
l = fread(Buf, 1, sizeof(Buf), fIn);
Crypt(Buf, &l, &pBuf);
Bin2ASCII(pBuf, l, &pOut);
fwrite(pOut, l*2, 1, fOut);
free(pBuf);
fclose(fIn);
fclose(fOut);
return 0;
}

Comments
Nike Aura Max+instagram, wishes you contain the color to be in on your feet!
Posted by madytreathy on 04/21/2013 09:36amRecognize in 2008, if not earlier, when Nike launched up ahead of the self-assured shoe color projects, the slogan "Bound Your Colours", "Nike PhotoiD" layout, [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache free[/url] response has not been as avid as expected. About, 2008 Canon IXUS 80 IS Digital card arcade but one 8 million pixels, Nokia, the facile phone superstore is the one leadership, NikeiD was support to color in the photos as a infrastructure for sneakers custom color, although provocative, but does bother some. Instagram which make this thing hold up to ridicule and simple, Nike PHOTOiD homeopathic upgrade customization services, recently [url=http://markwarren.org.uk/goodbuy.cfm]nike free run[/url] released a new plan. That such iD can you realize pictures as instagram account shoe color, the meanwhile put up Nike Aura Max shoes and Nike Style Max 1, Nike Affectedness Max 90 953 options. Interested in children's shoes, you [url=http://turbo-vac.co.uk/components_13.cfm]nike free womens[/url] can without exception conform with each other's proper website photoid.Nike.com, in reckoning to skim through other people's artistic charge, or you can struggle to upload your own instagram photo, physique your own Nike Mood Max.
ReplyYou demand some tomato basil and mozzarella. Into indoor press into waiting, these slippers are as be exposed and manueverable as sneakers.
Posted by Soaceddew on 04/19/2013 03:26amHas honourable released some mod color Democratic Inneva Woven shoes, Nike recently with another direction to bring shoes with different styling to all [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache[/url] eyes. This brings steadfast print run Let off Inneva Woven is a Creamy Marker of works in the series, represents shoes Italian made the assurance. Latest Allowed Inneva Woven swart and blue are readily obtainable in two color schemes, to hand-knit Woven vamp in extension to infiltrated Italy's [url=http://markwarren.org.uk/goodbuy.cfm]nike free uk[/url] finest crafts, meanwhile gives athletes terminate to the foot of ease, the most superior thing is the intent of Unstinting 5 configuration, barefoot be aware it resolution give birth to cannot be ignored. Nike Free Inneva Woven SP White Identify Pack on Walk 16 at outlets around the [url=http://northernroofing.co.uk/roofins.cfm]nike free run[/url] kind on the shelves, and on sale in minimal tone, interested friends should pay close attention to Nike announced the news.
ReplyStrangest behavior ever in any program in 25 years of programming
Posted by rightohor on 06/24/2005 11:14amThis is one of the most strange things ever. I have rearranged your code so that it will compile and even WORK using the Borland c++ E6 compiler. It is a very simple application with 3 memo boxes: 1) for the original text to encrypt, 2)for the ascii version of the encrypted text and 3) for the decrypted text, which should be identical to the first box. One button encrypts: void __fastcall TForm1::Button1Click(TObject *Sender) { // vamos a desncryptar lo que tenga mOrig unsigned char *pIn,*ppOut; long plSize=0; bool res; plSize = mOrig->Text.Length(); res = Crypt((unsigned char*)mOrig->Text.c_str(),&plSize,&ppOut); if(!res) { ShowMessage("Encryption has failed"); return; } // pIn[plSize]=0; res = Bin2ASCII(ppOut,plSize,&pIn); if(!res) { ShowMessage("Binary to ASCII has failed"); return; } else mCrypted->Text=AnsiString((char*)pIn); free(ppOut); free(pIn); } And then, another button to DECRTYPT it: void __fastcall TForm1::Button2Click(TObject *Sender) { // vamos a desencryptar unsigned char *ppOut; long l; l = mCrypted->Text.Length(); ASCII2Bin(mCrypted->Text.c_str(),l,&ppOut); long l2; double d2; d2 = l/2; l2 = (long)d2; Decrypt(ppOut,&l2); ppOut[l2]=0; // the debugger has gone THIS FAR, but then it can't show the next line mDecrypted->Text=AnsiString((char*)ppOut); free(ppOut); } Please keep this in mind: IT WORKS ONE TIME. One time. It encrypts and decrypts. The second time, it can ENCRYPT, but it can't EVER decrypt. As you can see I've added some stupid code in order to see why it is failing. Even with the debugger active, the program goes crazy, giving this information: --------------------------- Information --------------------------- Project C:\pb6\ibadmin\comenc.exe faulted with message: 'access violation at 0x40009729: write of address 0x00030de0'. Process Stopped. Use Step or Run to continue. --------------------------- OK --------------------------- The above is not happenning within the lines of my code. If I change the lines, the same problem is generated somewhere else. With the debbuger I have been able to see it going past the DECRYPT() function, but it can not SHOW or copy the results to the memo object. I know this sounds crazy but, any ideas will be welcome. R I Ohoran Of course, neither step nor run are useable any more.ReplyStrangest behavior ever in any program in 25 years of programming
Posted by rightohor on 06/24/2005 11:02amThis is one of the most strange things ever. I have rearranged your code so that it will compile and even WORK using the Borland c++ E6 compiler. It is a very simple application with 3 memo boxes: 1) for the original text to encrypt, 2)for the ascii version of the encrypted text and 3) for the decrypted text, which should be identical to the first box. One button encrypts: void __fastcall TForm1::Button1Click(TObject *Sender) { // vamos a desncryptar lo que tenga mOrig unsigned char *pIn,*ppOut; long plSize=0; bool res; plSize = mOrig->Text.Length(); res = Crypt((unsigned char*)mOrig->Text.c_str(),&plSize,&ppOut); if(!res) { ShowMessage("Encryption has failed"); return; } // pIn[plSize]=0; res = Bin2ASCII(ppOut,plSize,&pIn); if(!res) { ShowMessage("Binary to ASCII has failed"); return; } else mCrypted->Text=AnsiString((char*)pIn); free(ppOut); free(pIn); } And then, another button to DECRTYPT it: void __fastcall TForm1::Button2Click(TObject *Sender) { // vamos a desencryptar unsigned char *ppOut; long l; l = mCrypted->Text.Length(); ASCII2Bin(mCrypted->Text.c_str(),l,&ppOut); long l2; double d2; d2 = l/2; l2 = (long)d2; Decrypt(ppOut,&l2); ppOut[l2]=0; // the debugger has gone THIS FAR, but then it can't show the next line mDecrypted->Text=AnsiString((char*)ppOut); free(ppOut); } Please keep this in mind: IT WORKS ONE TIME. One time. It encrypts and decrypts. The second time, it can ENCRYPT, but it can't EVER decrypt. As you can see I've added some stupid code in order to see why it is failing. Even with the debugger active, the program goes crazy, giving this information: --------------------------- Information --------------------------- Project C:\pb6\ibadmin\comenc.exe faulted with message: 'access violation at 0x40009729: write of address 0x00030de0'. Process Stopped. Use Step or Run to continue. --------------------------- OK --------------------------- The above is not happenning within the lines of my code. If I change the lines, the same problem is generated somewhere else. With the debbuger I have been able to see it going past the DECRYPT() function, but it can not SHOW or copy the results to the memo object. I know this sounds crazy but, any ideas will be welcome. R I Ohoran Of course, neither step nor run are useable any more.Replyis it the best one..............
Posted by Legacy on 07/25/2003 12:00amOriginally posted by: prabu
i appreciate ur work . its indeed a good try.
ReplyRead MSDN every time before...
Posted by Legacy on 08/02/2002 12:00amOriginally posted by: Arti
Hi,
Replysee MSDN examples - They are the same like your code.
CryptImportKey fail
Posted by Legacy on 07/31/2002 12:00amOriginally posted by: Thomas
ReplyAny demo project/source
Posted by Legacy on 03/01/2002 12:00amOriginally posted by: mok
I try to copy the source and put in a projects,but have some problem said that certain variable not declare. I already checked with MSDN and put all the file required. So, it will be nice if u can provide me a simple demo project. Thank
ReplyDoes not work in unicode
Posted by Legacy on 02/25/2002 12:00amOriginally posted by: Trevor
The program does not function when compiled as UNICODE
ReplyDoes it work now?
Posted by Legacy on 02/19/2002 12:00amOriginally posted by: Gerard J. Nicol
When I tried this code before it did not decrypt, have you fixed this now (you have not identified what has been updated).
Have you considered puting the code into an MFC class, it would be nice if the encrypted string was a CObject so that it could be easily serialized. You would also be able to separate the components of the encrypted string into separate members.
Anyway, keep up the good work Dr!
ReplyLoading, Please Wait ...