home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC-Online 1998 February
/
PCOnline_02_1998.iso
/
filesbbs
/
win95
/
cryptext.exe
/
decrypt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-04
|
5KB
|
228 lines
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "sha.h"
#include "rc4.h"
#define BUFFERSIZE 16384
#define KEYSIZE 20
union SHAKEY
{
DWORD keyW [KEYSIZE / sizeof (DWORD)];
BYTE keyB [KEYSIZE];
};
typedef struct tagIV
{
FILETIME fileTime;
int rand;
} IV, *LPIV;
union unionIV
{
IV iv;
BYTE byteIV [sizeof (IV)];
};
// functions
void LoadIV (HANDLE, LPBYTE);
BOOL CheckKeyIsValid (LPSTR, LPBYTE);
void CreateUniqueKey (LPDWORD, LPBYTE, LPIV);
int main (int argc, char *argv[])
{
union unionIV iv;
union SHAKEY key, uniqueKey;
rc4Key streamKey;
DWORD nBytesSoFar;
DWORD nBytesRead, nBytesWritten;
HANDLE hFile;
char szFile [_MAX_PATH];
char szNewFile [_MAX_PATH];
char szPass [_MAX_PATH];
BYTE lpFileBuffer [BUFFERSIZE];
// check parameters
// must be two parameters
if (argc != 3)
{
printf ("\nInvalid parameters. Command line must be:"
"\n\tDECRYPT \"<passphrase>\" <filename>"
"\n e.g.\tDECRYPT \"goggomobile\", C:\\TEMP\\TEST.TXT.$#!\n");
return 1;
}
// get passphrase and filename
lstrcpy (szPass, argv[1]);
lstrcpy (szFile, argv[2]);
// check for validity of passphrase
if (!CheckKeyIsValid (szPass, key.keyB))
return 1;
// open the file
hFile = CreateFile (szFile,
GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf ("\nError opening %s\n", szFile);
return 1;
}
// Load the iv
LoadIV (hFile, iv.byteIV);
// use the iv to create a unique key for this file
CreateUniqueKey (uniqueKey.keyW, key.keyB, &(iv.iv));
// do RC4 setup
rc4Setup (uniqueKey.keyB, KEYSIZE, &streamKey);
// decrypt the file
nBytesSoFar = 0;
do
{
// fill the buffer from the file
ReadFile (hFile, lpFileBuffer, BUFFERSIZE, &nBytesRead, NULL);
if (nBytesRead)
{
// encrypt or decrypt as required
rc4 (lpFileBuffer, nBytesRead, &streamKey);
// reset the file pointer for the write
SetFilePointer (hFile,
nBytesSoFar, // offset into file
NULL, // only using files < 2^32 in size
FILE_BEGIN); // starting point for offset
// write the buffer
WriteFile (hFile, lpFileBuffer, nBytesRead,
&nBytesWritten, NULL);
// increment byte count
nBytesSoFar += nBytesRead;
}
} while (nBytesRead);
// close the file
CloseHandle (hFile);
// rename the file to remove the encryption extension
lstrcpyn (szNewFile, szFile, lstrlen (szFile) - 3);
MoveFile (szFile, szNewFile);
// finish
return 0;
}
void
LoadIV (HANDLE hFile, LPBYTE ivAsBytes)
{
DWORD nBytesRead;
// set the pointer to the beginning of the iv
SetFilePointer (hFile, 0-(sizeof(IV)+KEYSIZE), NULL, FILE_END);
// read the iv
ReadFile (hFile, ivAsBytes, sizeof (IV), &nBytesRead, NULL);
// set the pointer to the last real byte in the file
SetFilePointer (hFile, 0-(sizeof(IV)+KEYSIZE), NULL, FILE_END);
// set the new EOF
SetEndOfFile (hFile);
// reset file pointer to the beginning of the file
SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
return;
}
BOOL
CheckKeyIsValid (LPSTR szPass, LPBYTE lpKey)
{
LONG dwErrorCode;
DWORD dwSize;
HKEY hKey;
union SHAKEY hashedKey, testKey;
char szKey [KEYSIZE*2+1];
char szTemp [_MAX_PATH+KEYSIZE+1];
// open the app key
dwErrorCode = RegOpenKeyEx (HKEY_CURRENT_USER,
"Software\\Cryptext\\Configuration",
0,
KEY_ALL_ACCESS,
&hKey);
// succeeded?
if (dwErrorCode != ERROR_SUCCESS)
{
printf ("\nPassword checksum not found in registry\n");
return FALSE;
}
else
{
// get the hashed encryption key from the registry
dwSize = KEYSIZE;
dwErrorCode = RegQueryValueEx (hKey,
"HashedKey",
NULL,
NULL,
hashedKey.keyB,
&dwSize);
// close the registry key
RegCloseKey (hKey);
}
// encryption key not found or key not 160 bits long
if (dwErrorCode != ERROR_SUCCESS || dwSize != KEYSIZE)
{
printf ("\nPassword checksum not found or invalid\n");
return FALSE;
}
sha_memory ((LPBYTE)szPass, lstrlen (szPass), testKey.keyW);
// copy the key
CopyMemory (lpKey, testKey.keyB, KEYSIZE);
// convert it to ASCII representation
wsprintf (szKey, "%08lx%08lx%08lx%08lx%08lx",
testKey.keyW[0], testKey.keyW[1], testKey.keyW[2], testKey.keyW[3], testKey.keyW[4]);
// add the hash to the password
wsprintf (szTemp, "%s%s", szPass, szKey);
// hash again
sha_memory ((LPBYTE)szTemp, lstrlen (szTemp), testKey.keyW);
// now verify against the stored hashed key
if (hashedKey.keyW[0] != testKey.keyW[0] ||
hashedKey.keyW[1] != testKey.keyW[1] ||
hashedKey.keyW[2] != testKey.keyW[2] ||
hashedKey.keyW[3] != testKey.keyW[3] ||
hashedKey.keyW[4] != testKey.keyW[4])
{
printf ("\nInvalid passphrase\n");
return FALSE;
}
return TRUE;
}
void
CreateUniqueKey (LPDWORD uniqueKey, LPBYTE lpKey, LPIV lpiv)
{
BYTE buffer [KEYSIZE + sizeof (IV)];
// copy hash of passphrase
CopyMemory (buffer, lpKey, KEYSIZE);
// copy date/time
CopyMemory (buffer+KEYSIZE, lpiv, sizeof (IV));
// hash to create key for rc4
sha_memory (buffer, KEYSIZE + sizeof (IV), uniqueKey);
}