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

📄 pk.cpp

📁 含有多种公开密钥算法、多种块加密、多种数据流加密、多种HASH函数、多种CheckSum校验、多种MAC校验等几十种加密算法的程序
💻 CPP
字号:
/* This file is in the public domain */#include <iostream>#include <fstream>#include <cctype>#include <string>#include <vector>#include <cstdio>#include <botan/rsa.h>#include <botan/rw.h>#include <botan/elgamal.h>#include <botan/dsa.h>#include <botan/nr.h>#include <botan/dh.h>#include <botan/look_pk.h>#include <botan/randpool.h>#include <botan/rng.h>using namespace Botan;SecureVector<byte> decode_hex(const std::string&);BigInt to_bigint(const std::string&);#define DEBUG 0class Fixed_Output_RNG : public RandomNumberGenerator   {   public:      byte random()         {         if(position < output.size())            return output[position++];         else            return 42;         }      void clear() throw() {}      std::string name() const { return "Fixed Output RNG"; }      void add_randomness(const byte[], u32bit) throw() {}      Fixed_Output_RNG(const SecureVector<byte>& x)         {         output = x;         position = 0;         }   private:      SecureVector<byte> output;      u32bit position;   };std::vector<std::string> parse(const std::string&);void strip(std::string&);u32bit validate_dsa_sig(const std::string&, const std::vector<std::string>&);u32bit validate_rsa_enc(const std::string&, const std::vector<std::string>&);u32bit validate_rsa_sig(const std::string&, const std::vector<std::string>&);u32bit validate_rsa_ver(const std::string&, const std::vector<std::string>&);u32bit validate_rw_sig(const std::string&, const std::vector<std::string>&);u32bit validate_nr_sig(const std::string&, const std::vector<std::string>&);u32bit validate_elg_enc(const std::string&, const std::vector<std::string>&);u32bit validate_dh(const std::string&, const std::vector<std::string>&);u32bit do_pk_validation_tests(const std::string& filename)   {   std::ifstream test_data(filename.c_str());   if(!test_data)       {       std::cout << "Couldn't open test file " << filename << std::endl;       std::exit(1);       }   u32bit errors = 0, alg_count = 0;   std::string algorithm;   while(!test_data.eof())      {      if(test_data.bad() || test_data.fail())         {         std::cout << "File I/O error." << std::endl;         std::exit(1);         }      std::string line;      std::getline(test_data, line);      strip(line);      if(line.size() == 0) continue;      // Do line continuation      while(line[line.size()-1] == '\\' && !test_data.eof())         {         line.replace(line.size()-1, 1, "");         std::string nextline;         std::getline(test_data, nextline);         strip(nextline);         if(nextline.size() == 0) continue;         line += nextline;         }      if(line[0] == '[' && line[line.size() - 1] == ']')         {         if(algorithm != "")            std::cout << std::endl;         algorithm = line.substr(1, line.size() - 2);         std::cout << "Testing " << algorithm << ": ";         alg_count = 0;         continue;         }      std::cout << ".";      std::cout.flush();      std::vector<std::string> substr = parse(line);#if DEBUG      std::cout << "Testing: " << algorithm << std::endl;#endif      u32bit new_errors = 0;      if(algorithm.find("DSA/") != std::string::npos)         new_errors = validate_dsa_sig(algorithm, substr);      else if(algorithm.find("NR/") != std::string::npos)         new_errors = validate_nr_sig(algorithm, substr);      else if(algorithm.find("RSAES/") != std::string::npos)         new_errors = validate_rsa_enc(algorithm, substr);      else if(algorithm.find("RSASSA/") != std::string::npos)         new_errors = validate_rsa_sig(algorithm, substr);      else if(algorithm.find("RSAVA/") != std::string::npos)         new_errors = validate_rsa_ver(algorithm, substr);      else if(algorithm.find("RWSSA/") != std::string::npos)         new_errors = validate_rw_sig(algorithm, substr);      else if(algorithm.find("ElGamal/") != std::string::npos)         new_errors = validate_elg_enc(algorithm, substr);      else if(algorithm.find("DHKAS/") != std::string::npos)         new_errors = validate_dh(algorithm, substr);      else         std::cout << "WARNING: Unknown PK algorithm "                   << algorithm << std::endl;      alg_count++;      errors += new_errors;      if(new_errors)         std::cout << "ERROR: \"" << algorithm << "\" failed test #"                   << std::dec << alg_count << std::endl;      }   std::cout << std::endl;   // reset the global rng, because validate_xxx will have replaced it   set_global_rng(new Randpool);   return errors;   }void dump_data(const SecureVector<byte>& out,               const SecureVector<byte>& expected)   {   // For whatever reason, I cannot figure out how to do this with cout...   std::printf("Got: ");   for(u32bit j = 0; j != out.size(); j++)      std::printf("%02X", out[j]);   std::printf("\nExp: ");   for(u32bit j = 0; j != expected.size(); j++)      std::printf("%02X", expected[j]);   std::printf("\n");   std::fflush(stdout);   }void validate_decryption(PK_Decryptor* d, const std::string& algo,                         const SecureVector<byte> ctext,                         const SecureVector<byte> ptext,                         bool& failure)   {   SecureVector<byte> decrypted = d->decrypt(ctext);   if(decrypted != ptext)      {      std::cout << "FAILED (decrypt): " << algo << std::endl;      dump_data(decrypted, ptext);      failure = true;      }   delete d;   }void validate_encryption(PK_Encryptor* e, PK_Decryptor* d,                         const std::string& algo, const std::string& input,                         const std::string& random, const std::string& exp,                         bool& failure)   {   SecureVector<byte> message = decode_hex(input);   set_global_rng(new Fixed_Output_RNG(decode_hex(random)));   SecureVector<byte> expected = decode_hex(exp);   SecureVector<byte> out = e->encrypt(message);   if(out != expected)      {      std::cout << "FAILED (encrypt): " << algo << std::endl;      dump_data(out, expected);      failure = true;      }   validate_decryption(d, algo, out, message, failure);   delete e;   }void validate_signature(PK_Verifier* v, PK_Signer* s, const std::string& algo,                        const std::string& input, const std::string& random,                        const std::string& exp, bool& failure)   {   SecureVector<byte> message = decode_hex(input);   set_global_rng(new Fixed_Output_RNG(decode_hex(random)));   SecureVector<byte> expected = decode_hex(exp);   SecureVector<byte> sig = s->sign_message(message, message.size());   if(sig != expected)      {      std::cout << "FAILED (sign): " << algo << std::endl;      dump_data(sig, expected);      failure = true;      }   if(!v->verify_message(message, message.size(), sig, sig.size()))      {      std::cout << "FAILED (verify): " << algo << std::endl;      failure = true;      }   /* This isn't a very thorough testing method, but it will hopefully      catch any really horrible errors */   sig[sig.size()-5]++;   if(v->verify_message(message, message.size(), sig, sig.size()))      {      std::cout << "FAILED (accepted bad sig): " << algo << std::endl;      failure = true;      }#if 0   delete v;   delete s;#endif   }void validate_kas(PK_Key_Agreement_Scheme* kas, const std::string& algo,                  const SecureVector<byte>& pubkey, const std::string& output,                  u32bit keylen, bool& failure)   {   SecureVector<byte> expected = decode_hex(output);   SecureVector<byte> got = kas->derive_key(pubkey, keylen).copy();   if(got != expected)      {      std::cout << "FAILED: " << algo << std::endl;      dump_data(got, expected);      failure = true;      }   delete kas;   }u32bit validate_rsa_enc(const std::string& algo,                        const std::vector<std::string>& str)   {   if(str.size() != 6)      throw Exception("Invalid input from pk_valid.dat");   RSA_PrivateKey privkey(to_bigint(str[1]), to_bigint(str[2]),                          to_bigint(str[0]));   RSA_PublicKey pubkey = privkey;   std::string eme = algo.substr(6, std::string::npos);   PK_Encryptor* e = get_pk_encryptor(pubkey, eme);   PK_Decryptor* d = get_pk_decryptor(privkey, eme);   bool failure = false;   validate_encryption(e, d, algo, str[3], str[4], str[5], failure);   return (failure ? 1 : 0);   }u32bit validate_elg_enc(const std::string& algo,                        const std::vector<std::string>& str)   {   if(str.size() != 6 && str.size() != 7)      throw Exception("Invalid input from pk_valid.dat");   DL_Group domain(to_bigint(str[0]), to_bigint(str[1]));   ElGamal_PrivateKey privkey(domain, to_bigint(str[2]), to_bigint(str[3]));   ElGamal_PublicKey pubkey = privkey;   std::string eme = algo.substr(8, std::string::npos);   PK_Decryptor* d = get_pk_decryptor(privkey, eme);   bool failure = false;   if(str.size() == 7)      {      PK_Encryptor* e = get_pk_encryptor(pubkey, eme);      validate_encryption(e, d, algo, str[4], str[5], str[6], failure);      }   else      validate_decryption(d, algo, decode_hex(str[5]),                          decode_hex(str[4]), failure);   return (failure ? 1 : 0);   }u32bit validate_rsa_sig(const std::string& algo,                        const std::vector<std::string>& str)   {   if(str.size() != 6)      throw Exception("Invalid input from pk_valid.dat");   RSA_PrivateKey privkey(to_bigint(str[1]), to_bigint(str[2]),                          to_bigint(str[0]));   RSA_PublicKey pubkey = privkey;   std::string emsa = algo.substr(7, std::string::npos);   PK_Verifier* v = get_pk_verifier(pubkey, emsa);   PK_Signer* s = get_pk_signer(privkey, emsa);   bool failure = false;   validate_signature(v, s, algo, str[3], str[4], str[5], failure);   return (failure ? 1 : 0);   }u32bit validate_rsa_ver(const std::string& algo,                        const std::vector<std::string>& str)   {   if(str.size() != 5) /* is actually 4, parse() adds an extra empty one */      throw Exception("Invalid input from pk_valid.dat");   RSA_PublicKey key(to_bigint(str[1]), to_bigint(str[0]));   std::string emsa = algo.substr(6, std::string::npos);   PK_Verifier* v = get_pk_verifier(key, emsa);   SecureVector<byte> msg = decode_hex(str[2]);   SecureVector<byte> sig = decode_hex(str[3]);   bool passed = v->verify_message(msg, msg.size(), sig, sig.size());   delete v;   return (passed ? 0 : 1);   }u32bit validate_rw_sig(const std::string& algo,                       const std::vector<std::string>& str)   {   if(str.size() != 6)      throw Exception("Invalid input from pk_valid.dat");   RW_PrivateKey privkey(to_bigint(str[1]), to_bigint(str[2]),                         to_bigint(str[0]));   RW_PublicKey pubkey = privkey;   std::string emsa = algo.substr(6, std::string::npos);   PK_Verifier* v = get_pk_verifier(pubkey, emsa);   PK_Signer* s = get_pk_signer(privkey, emsa);   bool failure = false;   validate_signature(v, s, algo, str[3], str[4], str[5], failure);   return (failure ? 1 : 0);   }u32bit validate_dsa_sig(const std::string& algo,                        const std::vector<std::string>& str)   {   if(str.size() != 8)      throw Exception("Invalid input from pk_valid.dat");   DL_Group domain(to_bigint(str[0]), to_bigint(str[1]), to_bigint(str[2]));   DSA_PrivateKey privkey(domain, to_bigint(str[4]), to_bigint(str[3]));   DSA_PublicKey pubkey = privkey;   std::string emsa = algo.substr(4, std::string::npos);   PK_Verifier* v = get_pk_verifier(pubkey, emsa);   PK_Signer* s = get_pk_signer(privkey, emsa);   bool failure = false;   validate_signature(v, s, algo, str[5], str[6], str[7], failure);   return (failure ? 1 : 0);   }u32bit validate_nr_sig(const std::string& algo,                       const std::vector<std::string>& str)   {   if(str.size() != 8)      throw Exception("Invalid input from pk_valid.dat");   DL_Group domain(to_bigint(str[0]), to_bigint(str[1]), to_bigint(str[2]));   NR_PrivateKey privkey(domain, to_bigint(str[4]), to_bigint(str[3]));   NR_PublicKey pubkey = privkey;   std::string emsa = algo.substr(3, std::string::npos);   PK_Verifier* v = get_pk_verifier(pubkey, emsa);   PK_Signer* s = get_pk_signer(privkey, emsa);   bool failure = false;   validate_signature(v, s, algo, str[5], str[6], str[7], failure);   return (failure ? 1 : 0);   }u32bit validate_dh(const std::string& algo,                   const std::vector<std::string>& str)   {   if(str.size() != 5 && str.size() != 6)      throw Exception("Invalid input from pk_valid.dat");   DL_Group domain(to_bigint(str[0]), to_bigint(str[1]));   DH_PrivateKey mykey(domain, to_bigint(str[2]));   DH_PublicKey otherkey(domain, to_bigint(str[3]));   std::string kdf = algo.substr(6, std::string::npos);   u32bit keylen = 0;   if(str.size() == 6)      keylen = to_u32bit(str[5]);   PK_Key_Agreement_Scheme* kas = get_pk_kas(mykey, kdf);   bool failure = false;   validate_kas(kas, algo, otherkey.public_value(),                str[4], keylen, failure);   return (failure ? 1 : 0);   }

⌨️ 快捷键说明

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