一、概述
TrueCrypt是唯一的一款支持WindowsVista/XP/2000/Linux开源的虚拟加密磁盘软件,能够创建和设置加密的虚拟磁盘镜像,虚拟磁盘可以与其它磁盘一样正常访问,内部所有文件 都会自动加密,需要通过密码来进行访问,加密和解密都是实时的。
TrueCrypt主要分为两部分;一部分是TrueCrypt Format,用来创建加密卷,另外一部分是TrueCryptMount,用来加载和卸载虚拟磁盘到分区等。
第一部分、TrueCrypt Format创建加密卷
按照TrueCrypt Format创建加密卷的向导,一共会出现加密卷位置,加密算法、加密卷大小、加密卷密码、加密卷格式化等几个步骤,之后就会创建加密卷,创建完的加密卷就是制定的加密卷位置的那个文件了。
因此我们知道TrueCrypt的核心就是创建加密卷函数了,该函数的作用就是接受上述的加密卷位置等几个参数,完成创建加密卷的过程,在TrueCrypt里的原型是
int
FormatVolume(
char *volumePath,
BOOL bDevice,
unsigned __int64 size,
unsigned __int64hiddenVolHostSize,
Password *password,
int cipher,
int pkcs5,
BOOL quickFormat,
BOOL sparseFileSwitch,
int fileSystem,
int clusterSize,
HWND hwndDlg,
BOOL hiddenVol,
int *realClusterSize,
BOOL uac
);
下面我们来看下每个参数具体的含义
参数 | 类型 | 含义 | 示例 |
volumePath | char * | 用户选择的加密卷文件 | C:\\1.txt |
bDevice | BOOL | 是否是一个分区卷 | FALSE |
size | unsigned __int64 | 加密卷大小(以byte为单位) | 10*1024*1024 |
hiddenVolHostSize | unsigned __int64 | 隐藏加密卷大小(以byte为单位) | 0 |
password | Password | 用户输入的密码 | 123456 |
cipher | int | 默认加密的算法 | 1 |
pkcs5 | int | 哈希算法 | DEFAULT_HASH_ALGORITHM |
quickFormat | BOOL | 是否是快速格式化 | FALSE |
sparseFileSwitch | BOOL |
| TRUE |
fileSystem | int | 文件系统 | FILESYS_FAT |
clusterSize | int |
| 0 |
hwndDlg | HWND | 传入的窗口句柄 | NULL |
hiddenVol | BOOL | 是否是隐藏卷 | FALSE |
realClusterSize | int |
| 512 |
uac | BOOL |
| FALSE |
下面我们来看具体的实例
int
Format( char* szFile,
unsigned __int64nsize,
char* szPassword,
HWND hwndDlg )
{
charszFileName[TC_MAX_PATH+1]; /* Thefile selected by the user */ charszDiskFile[TC_MAX_PATH+1]; /* Fullyqualified name derived from szFileName */
BOOL bDevice = FALSE; /* Is this apartition volume ? */
unsigned __int64 nVolumeSize= 0; /* The volume size, inbytes. */
unsigned __int64nHiddenVolHostSize = 0; /* Sizeof the hidden volume host, in bytes */
Password volumePassword; /* Users password */
int nVolumeEA = 1; /* Defaultencryption algorithm */
int hash_algo =DEFAULT_HASH_ALGORITHM; /* Which PRF touse in header key derivation (PKCS #5) and in the RNG. */
volatile BOOLbSparseFileSwitch = FALSE;
volatile BOOL quickFormat =FALSE; /* WARNING: Meaning of thisvariable depends on bSparseFileSwitch. */
/*
If bSparseFileSwitch is TRUE, this variable represents the sparse fileflag.
*/
volatile int fileSystem = 0;
volatile int clusterSize =0;
BOOL bHidden;
int realClusterSize; /*Parameter used when determining the maximum possible size of a hidden volume.*/
int nStatus;
char szTmp[16];
int nMultiplier = 1024*1024; /* Size selectionmultiplier. */
// strcpy(szDiskFile,"C:\\1.txt");
// szDiskFile[8] = 0;
strcpy(szDiskFile, szFile);
szDiskFile[strlen(szFile)] =0;
strcpy(szTmp,"10");
//nVolumeSize = _atoi64(szTmp);
nVolumeSize = nsize;
nVolumeSize = nVolumeSize *nMultiplier;
nHiddenVolHostSize = 0;
// strcpy(volumePassword.Text,"123456");
strcpy(volumePassword.Text,szPassword);
volumePassword.Length =strlen (volumePassword.Text);
quickFormat = FALSE;
bSparseFileSwitch = TRUE;
fileSystem = FILESYS_FAT;
clusterSize = 0;
bHidden = FALSE;
realClusterSize = 512;
nStatus = FormatVolume(szDiskFile,//
bDevice,//
nVolumeSize,//1024*1024*10
nHiddenVolHostSize,//0
&volumePassword,//
nVolumeEA,//
hash_algo,//
quickFormat,//FALSE
bSparseFileSwitch,//TRUE
fileSystem,//1
clusterSize,//0
hwndDlg,//
bHidden,//FALSE
&realClusterSize,//512
FALSE
);
return 1;
}
在进行了一系列的参数设置后,即可完成加密卷的设置工作,下面就可以进行创建了,通过以上方式就可以实现自己的创建加密卷的方法。TrueCrypt对加 密卷文件大小没有限制。虚拟的磁盘容量大小仅受加密卷所在磁盘的文件系统限制。例如,Fat32格式化的磁盘内,可以创建的加密卷文件不能超过4G。
2、TrueCryptMount加载虚拟磁盘
|
在创建完加密卷之后,怎么使用虚拟磁盘呢?这个时候需要加载虚拟磁盘,加载完虚拟磁盘后,就会在磁盘分区里多出一个分区,比如在我的电脑里可以看到一个新的本地磁盘 (L:)。那么,TrueCrypt里具体是怎么实现的?首先需要选择我们在上一步创建的加密卷,选择一个需要加载的分区,这其实就是在还没用到的分区卷 标里选择一个,之后点击载入载入即可,这个时候就会找到加密卷进行加载,这时会需要用户输入创建加密卷时的设定的密码,加载成功后,就能看到新虚拟出来的磁盘了。
因此,TrueCrypt另一个核心函数加载虚拟磁盘函数应该是接受加密卷、磁盘分区、用户密码等参数进行加载,该函数在TrueCrypt的原型是
int
MountVolume(
HWND hwndDlg,
int driveNo,
char *volumePath,
Password *password,
BOOL cachePassword,
BOOL sharedAccess,
MountOptions *mountOptions,
BOOL quiet,
BOOL bReportWrongPassword
)
下面我们来看下每个参数具体的含义
参数 | 类型 | 含义 | 示例 |
hwndDlg | HWND | 传入的窗口句柄 | NULL |
driveNo | int | 加载的磁盘分区序号 | 8 |
volumePath | char * | 用户选择的加密卷文件 | C:\\1.txt |
password | Password | 用户输入的密码 | 123456 |
cachePassword | BOOL | 是否采用缓存密码 | FALSE |
sharedAccess | BOOL |
| FALSE |
mountOptions | MountOptions | 加载选项 |
|
quiet | BOOL |
| FALSE |
bReportWrongPassword | BOOL | 是否报告错误的密码 | TRUE |
MountVolume函数返回结果为
-1 用户终止加载
0 加载失败
1 加载成功
2 在共享模式加载成功
下面我们来看具体的实例
int
Mount(char* szFile,
char* szPassword,
int nDriveNo,
HWND hwndDlg)
{
int nDosDriveNo;
charszFileName[TC_MAX_PATH+1]; /* Thefile selected by the user */
Password VolumePassword; /* Password used formounting volumes */
BOOL bCacheInDriver = FALSE; /* Cache any passwords wesee */
BOOL bForceMount = FALSE; /* Mount volume even if hostfile/device already in use */
MountOptions mountOptions;
int mounted = 0;
// nDosDriveNo = 8;
nDosDriveNo = nDriveNo;
// strcpy(szFileName,"C:\\1.txt");
// szFileName[8] = 0;
strcpy(szFileName, szFile);
szFileName[strlen(szFile)] =0;
bCacheInDriver = FALSE;
bForceMount = FALSE;
// strcpy(VolumePassword.Text,"123456");
strcpy(VolumePassword.Text,szPassword);
VolumePassword.Length =strlen (VolumePassword.Text);
mountOptions.PersistentVolume= 0;
mountOptions.PreserveTimestamp= 1;
strcpy(mountOptions.ProtectedHidVolPassword.Text,"");
mountOptions.ProtectedHidVolPassword.Length =0;
mountOptions.ProtectHiddenVolume = 0;
mountOptions.ReadOnly = 0;
mountOptions.Removable = 0;
mountOptions.SystemVolume =0;
mounted = MountVolume(
hwndDlg,
nDosDriveNo,
szFileName,
&VolumePassword,
bCacheInDriver,
bForceMount,
&mountOptions,
FALSE,
TRUE
);
if(mounted == 1) return 1;
else return 0;
return 1;
}
成功虚拟磁盘后,即会弹出虚拟出的磁盘,可以在虚拟磁盘里创建文件,在虚拟磁盘里的文件都会加密到用户指定的加密卷文件中,任何人想要看到虚拟磁盘里的文件,需要加载该虚拟磁盘并正确输入密码。
3、TrueCryptMount卸载虚拟磁盘
加载虚拟磁盘之后,可以创建受虚拟磁盘加密保护的文档,之后卸载虚拟磁盘,创建的文档则加密保存在加密卷中,这步操作起来比较简单,那么,在TrueCrypt实际是如何实现的呢?
TrueCrypt另一个核心函数卸载虚拟磁盘函数UnmountVolume,接受三个函数,分别是传入的窗口句柄、磁盘分区的序号和是否强制卸载的标识,其在TrueCrypt中的原型是
BOOL
UnmountVolume(
HWND hwndDlg,
int nDosDriveNo,
BOOL forceUnmount
)
下面我们来看下每个参数具体的含义
参数 | 类型 | 含义 | 示例 |
hwndDlg | HWND | 传入的窗口句柄 | NULL |
driveNo | int | 加载的磁盘分区序号 | 8 |
forceUnmount | BOOL | 是否强制卸载 | FALSE |
下面我们来看具体的实例
int
Unmount(int nDriveNo, HWND hwndDlg)
{
int nDosDriveNo;
int unmounted = 0;
BOOL bForceUnmount = FALSE;/* Unmount volume even if it cannot be locked */
// nDosDriveNo = 8;
nDosDriveNo = nDriveNo;
bForceUnmount = FALSE;
unmounted = UnmountVolume(
hwndDlg,
nDosDriveNo,
bForceUnmount
);
if(unmounted == 1) return 1;
else return 0;
}
当unmounted为1的时候卸载虚拟磁盘成功,为0的时候卸载失败,那么失败的原因有哪些呢?
1、UNMOUNT_FAILED 卸载出错
2、UNMOUNT_LOCK_FAILED 加载的虚拟磁盘打开或者虚拟磁盘内的文件还在打开等
当为第二种情况时,TrueCrypt的处理情形是提出提示,虚拟磁盘还打开着,提示用户是否强制卸载,如果强制卸载的话,创建的文件将不会保存,虚拟磁盘强制退出,如果不强制卸载的话,重复执行卸载虚拟磁盘的操作。
BOOL
UnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount)
{
int result;
BOOL forced = forceUnmount;
int dismountMaxRetries =UNMOUNT_MAX_AUTO_RETRIES;
retry:
BroadcastDeviceChange(DBT_DEVICEREMOVEPENDING, nDosDriveNo, 0);
do
{
result =DriverUnmountVolume (hwndDlg, nDosDriveNo, forced);
if (result ==ERR_FILES_OPEN)
Sleep(UNMOUNT_AUTO_RETRY_DELAY);
else break;
} while(--dismountMaxRetries > 0);
if (result != 0)
{
if (result ==ERR_FILES_OPEN && !Silent)
{
if (IDYES ==AskWarnNoYes ("UNMOUNT_LOCK_FAILED"))
{
forced =TRUE;
goto retry;
}
return FALSE;
}
Error ("UNMOUNT_FAILED");
return FALSE;
}
BroadcastDeviceChange (
DBT_DEVICEREMOVECOMPLETE,
nDosDriveNo,
0
);
return TRUE;
}
但是,有些应用场景不希望用户执行强制卸载的情况,因为那样的话,用户操作的文档则不会保存,因此需要继续友好的提示用户虚拟磁盘还继续打开着,因此我们可以当判断result == ERR_FILES_OPEN && !Silent的时候直接return FALSE,或者注释forced =TRUE,一直提示用户,可以根据具体的应用场景加以修改。
4、TrueCryptMount更改加密卷密码
在实际的应用中,TrueCrypt可以很好地与业务系统相结合,比如,为不同的用户创建各自的加密卷,用户登录业务系统即加载各自的虚拟磁盘,那么面对业务系统中平常的修改密码操作,TrueCrypt也能够应付自如。
在TrueCrypt中,提供了修改加密卷密码的接口,该函数在TrueCrypt中的原型是
int ChangePwd (
char *lpszVolume,
Password *oldPassword,
Password *newPassword,
int pkcs5,
HWND hwndDlg
);
下面我们来看下每个参数具体的含义
参数 | 类型 | 含义 | 示例 |
lpszVolume | char * | 加密卷文件 | NULL |
oldPassword | Password | 原密码 |
|
newPassword | Password | 新密码 |
|
pkcs5 | int | 哈希算法 | 0 |
hwndDlg | HWND | 传入的窗口句柄 | NULL |
下面我们来看具体的实例
int
ChangePassword(char*szFile,
char* szoldPassword,
char* sznewPassowrd,
HWND hwndDlg)
{
char szFileName[TC_MAX_PATH+1];
int nStatus;
Password oldPassword;
Password newPassword;
int pkcs5;
strcpy(szFileName, szFile);
szFileName[strlen(szFile)] = 0;
strcpy(oldPassword.Text, szoldPassword);
oldPassword.Length = strlen(oldPassword.Text);
strcpy(newPassword.Text, sznewPassowrd);
newPassword.Length = strlen (newPassword.Text);
pkcs5 = 0;
nStatus = ChangePwd (szFileName,
&oldPassword,
&newPassword,
pkcs5, hwndDlg);
if (nStatus == ERR_OS_ERROR &&
GetLastError () ==ERROR_ACCESS_DENIED &&
IsUacSupported () &&
IsVolumeDeviceHosted (szFileName)
)
{
WaitCursor ();
nStatus = UacChangePwd (
szFileName,
&oldPassword,
&newPassword,
pkcs5, hwndDlg
);
NormalCursor ();
}
burn ( &oldPassword, sizeof(oldPassword) );
burn ( &newPassword, sizeof(newPassword) );
if (nStatus == 0) {
return 1;
}
return 0;
}