📄 rsa_enc.cpp
字号:
/*Grab an RSA public key from the file given as an argument, grab a messagefrom another file, and encrypt the message.Algorithms used: RSA with EME1(SHA-1) padding to encrypt the master key CAST-128 in CBC mode with PKCS#7 padding to encrypt the message. HMAC with SHA-1 is used to authenticate the messageThe keys used are derived from the master key (the thing that's encrypted withRSA) using MD5. The master key is prefixed with some value P, where P is"CAST", "IV" or "MAC", in order to parameterize the output for each key. Thekeys for CAST-128 and HMAC are used as-is, while the output used for the IV istruncated (the first half is used).Note that the key format is just a pair of lines, first one is the exponent,second one is the modulus. No provisions for anything complicated... that's whythis is only an example program.Written by Jack Lloyd (lloyd@randombit.net), June 3, 2002This file is in the public domain*/#include <iostream>#include <iomanip>#include <fstream>#include <cstdlib>#include <string>#include <botan/lookup.h>#include <botan/look_pk.h>#include <botan/filters.h>#include <botan/rsa.h>#include <botan/cbc.h>using namespace Botan;std::string b64_encode(const SecureVector<byte>&);SymmetricKey derive_key(const std::string&, const SymmetricKey&, u32bit);void write_bigint_to_pipe(Pipe&, const BigInt&);int main(int argc, char* argv[]) { try { if(argc != 3) { std::cout << "Usage: rsa_enc keyfile messagefile" << std::endl; return 1; } std::ifstream keyfile(argv[1]); if(!keyfile) { std::cout << "Couldn't read the key file." << std::endl; return 1; } std::ifstream message(argv[2]); if(!message) { std::cout << "Couldn't read the message file." << std::endl; return 1; } std::string output_name(argv[2]); output_name += ".enc"; std::ofstream ciphertext(output_name.c_str()); if(!ciphertext) { std::cout << "Couldn't write the ciphertext to " << output_name << std::endl; return 1; } LibraryInitializer init; std::string e, n; getline(keyfile, e); getline(keyfile, n); RSA_PublicKey key(n, e); if(!key.check_params()) { std::cout << "The public key seems to be invalid" << std::endl; return 1; } PK_Encryptor encryptor(key, "EME1(SHA-1)"); SymmetricKey masterkey(16); if(masterkey.length() > encryptor.maximum_input_size()) { std::cout << "Sorry, this RSA key is too small to encrypt a session key " "that is " << masterkey.length() << " bytes long\n"; return 1; } SymmetricKey cast_key = derive_key("CAST", masterkey, 16); SymmetricKey mac_key = derive_key("MAC", masterkey, 16); SymmetricKey iv = derive_key("IV", masterkey, 8); SecureVector<byte> encrypted_key = encryptor.encrypt(masterkey.value()); ciphertext << b64_encode(encrypted_key) << std::endl; Pipe pipe(new Fork( new Chain( new CBC_Encryption("CAST-128", "PKCS7", cast_key, iv), new Base64_Encoder(true) ), new Chain( new MAC_Filter("HMAC(SHA-1)", mac_key, 12), new Base64_Encoder ) ) ); pipe.start_msg(); message >> pipe; pipe.end_msg(); /* Write the MAC as the second line. That way we can pull it off right from the start, and feed the rest of the file right into a pipe on the decrypting end. */ ciphertext << pipe.read_all_as_string(1) << std::endl; ciphertext << pipe.read_all_as_string(0); } catch(Exception& e) { std::cout << "Exception caught: " << e.what() << std::endl; } catch(std::exception& e) { std::cout << "Standard library exception caught: " << e.what() << std::endl; } catch(...) { std::cout << "Unknown exception caught." << std::endl; } return 0; }std::string b64_encode(const SecureVector<byte>& in) { Pipe pipe(new Base64_Encoder); pipe.start_msg(); pipe.write(in, in.size()); pipe.end_msg(); return pipe.read_all_as_string(); }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 + -