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

  • • Le site officiel du GHD a une liste de tous les sites ghd faux connus

    Posted by khzbas155 on 07/16/2013 12:56pm

    Admirateurs de fer GHD sont en nombre croissant et devraient continuer à increase.As ces caractéristiques uniques rettetanghar GHD qui n'abîment pas les cheveux, vous pouvez les utiliser régulièrement pour coiffer vos cheveux. Divisez vos cheveux en plusieurs sections afin de rendre le processus plus rapidement. Maintenez le lisseur légèrement et faites glisser depuis le sommet jusqu'à la pointe des cheveux, faire pression sur les cheveux raides n'est tout simplement pas nécessaire lorsque vous utilisez tige de style. Application Lisseur GHD légèrement suffit à maintenir belles et élégantes jours de cheveux de hair.Good sont difficiles à trouver avec la pollution croissante et la poussière. Cependant, ghd créé à cet effet, de sorte que vous pouvez être sûr que vos problèmes sont guéris. [url=http://ghdpascherfer.hpage.com/]lisseur ghd pas cher[/url] Katy Perry est magnifique, peu importe ce qu'elle porte. Pas beaucoup de femmes seraient correspondre ses cheveux à sa tenue, mais Katy Perry est l'exception. Le cheveu est un arc en ciel toujours changeant, et en ce moment elle a choisi un purple.I sombre vraiment l'amour de sirène regarder cependant, il ya quelque chose de si pur innocent à ce sujet, et je pense que c'est une merveilleuse idée que GHD utiliser cette image à leur annonce. Ça me fait penser, naturellement, venteux et lunatique. [url=http://ghdpascherfer.tripod.com/]lisseur ghd pas cher[/url] Source GHD d'inspiration provient de toutes les directions, et lance bague av la nouvelle édition limitée GHD, GHD et symbole de luxe, kombinert avec un paon chaud et beau, paon inspirert Utforme un charismatique Peacock GHD rettetang.Hot Vente GHD Purple Limited Edition Peacock, au nom organisme officiel av , profondeur prestisje et spirituelle. Le paon pourpre droit tige Bruke rik émeraude pourpre, paon Chaque tige droite ghd a tout funksjonene l'articulation, un ghd Gold Classic Styler avec fargede plaqueur et aksenter, et une plaque de protection suscité, avec un oppbevaringspose luxe et rull terne.

    Reply
  • Nike Aura Max+instagram, wishes you contain the color to be in on your feet!

    Posted by madytreathy on 04/21/2013 09:36am

    Recognize 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.

    Reply
  • You 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:26am

    Has 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.

    Reply
  • Strangest behavior ever in any program in 25 years of programming

    Posted by rightohor on 06/24/2005 11:14am

    This 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.

    Reply
  • Strangest behavior ever in any program in 25 years of programming

    Posted by rightohor on 06/24/2005 11:02am

    This 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.

    Reply
  • is it the best one..............

    Posted by Legacy on 07/25/2003 12:00am

    Originally posted by: prabu

    i appreciate ur work . its indeed a good try.

    Reply
  • Read MSDN every time before...

    Posted by Legacy on 08/02/2002 12:00am

    Originally posted by: Arti

    Hi,
    see MSDN examples - They are the same like your code.

    Reply
  • CryptImportKey fail

    Posted by Legacy on 07/31/2002 12:00am

    Originally posted by: Thomas

    The call of CryptImportKey failed with error: NTE_BAD_VER. The error means: "The key blob's version number does not match the CSP version. This usually indicates that the CSP needs to be upgraded." Where can i get an upgraded?
    
    

    thanks
    Thomas

    Reply
  • Any demo project/source

    Posted by Legacy on 03/01/2002 12:00am

    Originally 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

    Reply
  • Does not work in unicode

    Posted by Legacy on 02/25/2002 12:00am

    Originally posted by: Trevor

    The program does not function when compiled as UNICODE

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Live Event Date: November 13, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT APIs can be a great source of competitive advantage. The practice of exposing backend services as APIs has become pervasive, however their use varies widely across companies and industries. Some companies leverage APIs to create internal, operational and development efficiencies, while others use them to drive ancillary revenue channels. Many companies successfully support both public and private programs from the same API by varying levels …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds