一个文件加密解密软件的源代码,可以设置很多著名的加密算法进行加密解密。它集强力、安全的算法和简单、易用的界面于一身。它的文件管理界面可以轻易地观看和更改整个系 统的加密设置,也可以加/解密选定的文件,安全地删除文件。它支持多用户使用。如图:
项目需要用到第三方库cryptlib,该库已经放到源码包中。
本程序有一个动态链接库NeoCryptSX与一个主程序Neocrypt组成,NeoCryptSX动态库操作简单,只负责发送调用消息,Neocrypt主程序中封装了Decryptor类负责解码、Encryptor类负责编码,File类负责文件操作、CProgUpdater类负责进度等。
解码部分:
void Decryptor::decrypt(const std::string& name,std::list<std::string>& pwds)
{
char* buf = new char[BUFFER_SIZE];
File file(name);
// pass file size to listener
if (mListener)
mListener->setRange(file.size());
// check for password
if (pwds.size() == 0)
throw std::logic_error("No passwords specified!");
// create the envelope
CRYPT_ENVELOPE env;
if (cryptCreateEnvelope(&env,CRYPT_UNUSED,CRYPT_FORMAT_AUTO))
throw std::runtime_error("Failed to create envelope!");
cryptSetAttribute(env,CRYPT_ATTRIBUTE_BUFFERSIZE,BUFFER_SIZE);
int n;
while (!file.eof() && (n = file.read(buf,BUFFER_SIZE-4096)) != 0)
{
int cBytes;
int bytesDone = 0;
int bytesLeft = n;
while (bytesLeft)
{
int status = cryptPushData(env,buf+bytesDone,bytesLeft,&cBytes);
if ( status == CRYPT_ENVELOPE_RESOURCE)
{
// add passwords until one is accepted
std::list<std::string>::iterator it;
std::list<std::string>::iterator end = pwds.end();
for (it = pwds.begin(); it != end; ++it)
{
// loop through all required attributes and try the password with each
if (cryptSetAttribute(env,CRYPT_ENVINFO_PASSWORD,CRYPT_CURSOR_FIRST) == CRYPT_OK)
{
bool accept = false;
do
{
CRYPT_ATTRIBUTE_TYPE attrib;
cryptGetAttribute(env,CRYPT_ENVINFO_PASSWORD,(int*)&attrib);
if (attrib == CRYPT_ENVINFO_PASSWORD)
{
if (cryptSetAttributeString(env,CRYPT_ENVINFO_PASSWORD,it->c_str(),it->size()) == CRYPT_OK)
{
accept = true;
break;
}
}
}
while (cryptSetAttribute(env,CRYPT_ENVINFO_PASSWORD,CRYPT_CURSOR_NEXT) == CRYPT_OK);
if (accept)
break;
}
}
if (it == end)
throw std::runtime_error("None of the passwords are valid for file " + name + " ! Please try another password.");
}
else if (status != 0)
{
throw std::runtime_error("The given file " + name + " is not a valid encrypted file.");
}
bytesLeft -= cBytes;
bytesDone += cBytes;
cryptPopData(env,buf,BUFFER_SIZE,&cBytes);
file.write(buf,cBytes);
}
if (mListener)
mListener->increment(n);
}
// flush remaining data
cryptFlushData(env);
cryptPopData(env,buf,BUFFER_SIZE,&n);
file.write(buf,n);
// destroy envelope
cryptDestroyEnvelope(env);
// close file
file.close();
mListener->complete();
delete [] buf;
}
编码部分:
void Encryptor::encrypt(const std::string& name,std::list<std::string>& password,Algorithm::Type algo)
{
char* buf = new char[BUFFER_SIZE];
File file(name);
// pass file size to listener
if (mListener)
mListener->setRange(file.size());
// check for at-least one password
if (password.size() == 0)
throw std::logic_error("No password in password list!");
// set algorithm type
if (cryptSetAttribute(CRYPT_UNUSED,CRYPT_OPTION_ENCR_ALGO,algo))
throw std::runtime_error("Could not set algorithm type!");
// create the envelope
CRYPT_ENVELOPE env;
if (cryptCreateEnvelope(&env,CRYPT_UNUSED,CRYPT_FORMAT_CRYPTLIB))
throw std::runtime_error("Failed to create envelope!");
std::list<std::string>::iterator i;
std::list<std::string>::iterator e = password.end();
// add password(s)
for (i = password.begin(); i != e; ++i)
{
if (cryptSetAttributeString(env,CRYPT_ENVINFO_PASSWORD,(*i).c_str(),(*i).size()))
throw std::runtime_error("Failed to set password " + (*i) + "!");
}
// allocate encryption buffer
if (cryptSetAttribute(env,CRYPT_ATTRIBUTE_BUFFERSIZE,BUFFER_SIZE))
throw std::runtime_error("Could not allocate encryption buffer!");
int n;
int cBytes;
if (!file.eof() && (n = file.read(buf,100)) != 0)
{
cryptPushData(env,buf,n,&cBytes);
cryptPopData(env,buf,BUFFER_SIZE,&cBytes);
file.write(buf,cBytes);
if (mListener)
mListener->increment(n);
}
while (!file.eof() && (n = file.read(buf,BUFFER_SIZE-4096)) != 0)
{
cryptPushData(env,buf,n,&cBytes);
cryptPopData(env,buf,BUFFER_SIZE,&cBytes);
file.write(buf,cBytes);
if (mListener)
mListener->increment(n);
}
// flush remaining data
cryptFlushData(env);
cryptPopData(env,buf,BUFFER_SIZE,&cBytes);
file.write(buf,cBytes);
// destroy envelope
cryptDestroyEnvelope(env);
// close file
file.close();
mListener->complete();
delete [] buf;
}
学习的目的是成熟!~