您的位置:首页 > 其它

使用Crypto++加解密类库实现密码管理系统

2016-04-19 22:26 417 查看
       Crypto++是一个免费的加解密类库,集成了很多的加解密算法,如des, aes, rsa等基础加密算法。本文主要谈一下本人最近实现的一个密码管理器,编译环境是32位Ubuntu,主要实现了多用户系统,可以创建用户、创建完成之后将密码经过HMAC存入用户文件、用户登录后需要对用户文件进行完整性检测保证外部修改、添加删除修改查看密码记录、记录以(域名、aes加密后密码、前两者结合的HMAC)形式存入文件。

程序架构

        由于管理器采用终端显示设计,就是说不同的代码段会不停地被调用。如果程序设计得不好的话,容易造成函数的嵌套调用,甚至栈空间无法释放,内存泄露等问题。为了避免这个问题,使用函数指针来规划整一个程序,有点像回调函数的感觉。整个管理器在运行时维护一个函数指针,每一次的函数调用都由这个指针来指定,而且保证每一个函数都执行完毕,避免函数变量占用栈空间。

typedef void (*func)();<span style="font-family: Arial, Helvetica, sans-serif;">     </span>


        以上代码定义了一个指针类型func,该指针类型可以指向一个返回值为void、0个参数的函数。因此,定义的功能函数中,都需要保证符合这一指针类型。

整体流程:


  

int main(){

printWelcome();

processor();      // run the procession

return 0;
}
func iter_func = main_page;

// the processor interface
void  processor(){

while( iter_func != NULL){
(*iter_func)();
}
//quit
cout <<  "bye!\n" << endl;
}




使用Crypto++进行HMAC运算

HMAC只能用来进行校验,不能用来加密,因此可以用来做密码验证的作用,类似于md5。

// check hmac of a domain with its password
string check_hmac(string infor, string key){
string mac, encoder;
string derived;
HexDecoder  decoder (new StringSink(derived));
decoder.Put((const byte*)key.data(), key.size());
decoder.MessageEnd();
try{
HMAC<SHA256> hmac((const byte*)derived.data(), derived.size());
StringSource(infor, true, new HashFilter(hmac, new StringSink(mac)));
}catch(const CryptoPP::Exception& e){
cerr << e.what() << endl;
exit(1);
}
encoder.clear();
StringSource(mac, true, new HexEncoder(new StringSink(encoder)));
return encoder;     //return HMAC
}


使用crypto++进行AES加解密

AES算法有较强的安全性,可以用来做密码的加密。当需要查询密码时,可以采用解密方式解出来。

string aes_decrypt(string password, string key){
// decrypt the password
string recovered;
string derived;
HexDecoder decoder(new StringSink(derived));
decoder.Put( (byte*)key.data(),key.size() );
decoder.MessageEnd();

string cipher;
HexDecoder decoder2(new StringSink(cipher));
decoder2.Put( (byte*)password.data(), password.size() );
decoder2.MessageEnd();
try{
CFB_Mode< AES >::Decryption d;
d.SetKeyWithIV((byte*)derived.data(), derived.size(),iv);
StringSource s(cipher, true, new StreamTransformationFilter(d,new StringSink(recovered)));
}catch(const CryptoPP::Exception& e){
cerr << e.what() << endl;
exit(1);
}
return recovered;
}

string aes_encrypt(string password, string key){
//to do
string cipher, encoded;

string derived;
HexDecoder decoder(new StringSink(derived));
decoder.Put((byte*)key.data(), key.size() );
decoder.MessageEnd();
try{
CFB_Mode< AES >::Encryption e;
e.SetKeyWithIV((byte*)derived.data(), derived.size(), iv);
StringSource(password, true, new StreamTransformationFilter(e, new StringSink(cipher)) );
}catch(const CryptoPP::Exception& e){
cerr << e.what() << endl;
exit(1);
}
encoded.clear();
StringSource(cipher, true,new HexEncoder(new StringSink(encoded)) );
return encoded;
}


整体实现

完整代码放在https://github.com/Jreffery/PasswordManager,有兴趣的朋友可以看一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: