⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsa_dec.cpp

📁 含有多种公开密钥算法、多种块加密、多种数据流加密、多种HASH函数、多种CheckSum校验、多种MAC校验等几十种加密算法的程序
💻 CPP
字号:
/*Decrypt (and verify) an encrypted RSA private key. Then use that key to decrypta message. This program can decrypt messages generated by rsa_enc, and uses thesame key format as that generated by rsa_kgen.Written by Jack Lloyd (lloyd@randombit.net), June 3-5, 2002This file is in the public domain*/#include <iostream>#include <iomanip>#include <fstream>#include <cstdlib>#include <string>#include <botan/filters.h>#include <botan/look_pk.h>#include <botan/lookup.h>#include <botan/rsa.h>#include <botan/cbc.h>#include <botan/pgp_s2k.h>using namespace Botan;using namespace std;SecureVector<byte> b64_decode(const std::string&);SymmetricKey derive_key(const std::string&, const SymmetricKey&, u32bit);BigInt pop_bigint(Pipe&);const std::string SUFFIX = ".enc";int main(int argc, char* argv[])   {   try {   if(argc != 4)      {      cout << "Usage: rsa_dec keyfile messagefile passphrase" << endl;      return 1;      }   ifstream keyfile(argv[1]);   if(!keyfile)      {      cout << "Couldn't read the key file." << endl;      return 1;      }   LibraryInitializer init;   std::string salt_str, mac_str;   std::getline(keyfile, salt_str);   std::getline(keyfile, mac_str);   // rest of keyfile should be the encrypted key   OpenPGP_S2K s2k("SHA-1", 8192);   s2k.change_salt(b64_decode(salt_str));   std::string passphrase(argv[3]);   SymmetricKey cast_key = s2k.derive_key("CAST" + passphrase, 16);   BlockCipherModeIV iv = s2k.derive_key("IV" + passphrase, 8);   SymmetricKey mac_key = s2k.derive_key("MAC" + passphrase, 16);   // we keep a reference around so we can reset the keys later   Keyed_Filter *cast, *hmac;   Pipe pipe(new Base64_Decoder,             cast = new CBC_Decryption("CAST-128", "PKCS7", cast_key, iv),             new Fork(                0,                new Chain(                   hmac = new MAC_Filter("HMAC(SHA-1)", mac_key, 12),                   new Base64_Encoder                   )                )      );   try {   pipe.start_msg();   keyfile >> pipe;   pipe.end_msg();   }   catch(Decoding_Error)      {      std::cout << "Bad decrypt of key file (bad passphrase?)\n";      return 1;      }   std::string our_mac = pipe.read_all_as_string(1);   /* 99% of the time, the PKCS7 padding code will detect a bad passphrase,      so really, the MAC isn't too useful, but whatever */   if(our_mac != mac_str)      {      std::cout << "MACs in keyfile failed to verify (bad passphrase?)\n";      return 1;      }   BigInt e = pop_bigint(pipe);   BigInt p = pop_bigint(pipe);   BigInt q = pop_bigint(pipe);   RSA_PrivateKey rsakey(p, q, e);   ifstream message(argv[2]);   if(!message)      {      cout << "Couldn't read the message file." << endl;      return 1;      }   std::string outfile(argv[2]);   outfile = outfile.replace(outfile.find(SUFFIX), SUFFIX.length(), "");   ofstream plaintext(outfile.c_str());   if(!plaintext)      {      cout << "Couldn't write the plaintext to " << outfile << endl;      return 1;      }   std::string enc_masterkey_str;   std::getline(message, enc_masterkey_str);   SecureVector<byte> enc_masterkey = b64_decode(enc_masterkey_str);   PK_Decryptor decryptor(rsakey, "EME1(SHA-1)");   SecureVector<byte> masterkey = decryptor.decrypt(enc_masterkey);   cast->reset_key(derive_key("CAST", masterkey, 16));   cast->reset_iv(derive_key("IV",   masterkey, 8));   hmac->reset_key(derive_key("MAC",  masterkey, 16));   std::getline(message, mac_str);   pipe.start_msg();   message >> pipe;   pipe.end_msg();   // Don't mind this. It's just some error checking for the garbage collection   // stuff in Pipe. It doesn't need to be here in a normal program.   if(pipe.remaining(0) || pipe.remaining(1))      throw Exception("pipe(0,1) not empty. Please email lloyd@randombit.net");   our_mac = pipe.read_all_as_string(3);   if(our_mac != mac_str)      std::cerr << "WARNING: MAC in message failed to verify\n";   plaintext << pipe.read_all_as_string(2);   }   catch(Exception& e)      {      cout << "Exception caught: " << e.what() << endl;      }   catch(exception& e)      {      cout << "Standard library exception caught: " << e.what() << endl;      }   catch(...)      {      cout << "Unknown exception caught." << endl;      }   return 0;   }SecureVector<byte> b64_decode(const std::string& in)   {   Botan::Pipe pipe(new Botan::Base64_Decoder);   pipe.start_msg();   pipe.write(in);   pipe.end_msg();   return pipe.read_all();   }/* 4 bytes for the length is completely excessive. Hell, 1 byte will handle it   most of the time (up to 2K bits), and 2 bytes is plenty for anything.   Whatever.*/BigInt pop_bigint(Pipe& pipe)   {   byte len[4];   if(pipe.remaining() < 4)      throw Exception("pop_bigint: Not enough bytes left (invalid file?)");   pipe.read(len, 4);   u32bit length = make_u32bit(len[0], len[1], len[2], len[3]);   if(pipe.remaining() < length)      throw Exception("pop_bigint: Not enough bytes left (invalid file?)");   byte* buf = new byte[length];   pipe.read(buf, length);   BigInt n(buf, length);   delete[] buf;   return n;   }SymmetricKey derive_key(const std::string& param,                        const SymmetricKey& masterkey,                        u32bit outputlength)   {   if(outputlength > 16)      throw Exception("Can't derive a key longer than 16 bytes with MD5");   HashFunction* md5 = get_hash("MD5");   md5->update(param);   md5->update(masterkey, masterkey.length());   SecureVector<byte> hash = md5->final();   delete md5;   return SymmetricKey(hash, outputlength);   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -