📄 dsa_kgen.cpp
字号:
/*Generate a 1024 bit DSA key and put it into a file. The public key is writtenin plaintext as 4 decimal values (g, p, q, and y), the private key is encryptedusing CAST-128 in CBC mode, and MACed with HMAC-SHA1-96 (the domain parametersand public value are also stored in the private key file).The domain parameters are the ones specified as the Java default DSAparameters. There is nothing special about these, it's just the only 1024-bitDSA parameter set that's included in Botan at the time of this writing. Theapplication always reads/writes all of the domain parameters to/from the file,so a new set could be used without any problems.The keys/ivs used for encrypting the private key are derived using OpenPGP'sS2K algorithm, with an 8 byte salt (which is written as the first 8 bytes ofthe private key file), and an iteration count of 8192. The passphrase isprefixed with a string to make sure that each one is different, and hopefullynot derivable from one another.The CAST key uses a prefix of "CAST"The HMAC key uses a prefix of "MAC"The IV uses a prefix of "IV"Written by Jack Lloyd (lloyd@randombit.net), August 5, 2002Heavily based on the rsa_kgen example. In fact the differences are quiteminimal, except that you can't specify a bitsize for the key, it's hardcodedat 1024 bits.This file is in the public domain*/#include <iostream>#include <iomanip>#include <fstream>#include <cstdlib>#include <string>#include <botan/filters.h>#include <botan/dsa.h>#include <botan/pgp_s2k.h>#include <botan/cbc.h>using namespace Botan;std::string b64_encode(const byte[], u32bit);void write_bigint_to_pipe(Pipe&, const BigInt&);int main(int argc, char* argv[]) { try { if(argc != 2) { std::cout << "Usage: dsa_kgen passphrase" << std::endl; return 1; } std::string passphrase(argv[1]); std::ofstream priv("dsakey.priv"); std::ofstream pub("dsakey.pub"); if(!priv || !pub) { std::cout << "Couldn't write output files" << std::endl; return 1; } // Want to make sure the RNG has lots of entropy LibraryInitializer init("seed_rng egd_path=/var/run/egd-pool"); DSA_PrivateKey key(get_dl_group("DSA-1024")); pub << key.get_g() << "\n" << key.get_p() << "\n" << key.get_q() << "\n" << key.get_y() << std::endl; OpenPGP_S2K s2k("SHA-1", 8192, 8); 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); SecureVector<byte> salt = s2k.current_salt(); priv << b64_encode(salt, salt.size()) << 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(); write_bigint_to_pipe(pipe, key.get_g()); write_bigint_to_pipe(pipe, key.get_p()); write_bigint_to_pipe(pipe, key.get_q()); write_bigint_to_pipe(pipe, key.get_x()); write_bigint_to_pipe(pipe, key.get_y()); pipe.end_msg(); priv << pipe.read_all_as_string(1) << std::endl; priv << 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 byte in[], u32bit length) { Pipe pipe(new Base64_Encoder); pipe.start_msg(); pipe.write(in, length); pipe.end_msg(); return pipe.read_all_as_string(); }void write_bigint_to_pipe(Pipe& pipe, const BigInt& num) { SecureVector<byte> bits = num.binary_encode(); for(u32bit j = 0; j != 4; j++) pipe.write(get_byte(j, bits.size())); pipe.write(bits, bits.size()); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -