📄 dsa_sign.cpp
字号:
/*Decrypt (and verify) an encrypted DSA private key. Then use that key to sign amessage.Written by Jack Lloyd (lloyd@randombit.net), August 5, 2002Copied almost entirely from rsa_dec.cpp. Saves thought that way...This 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/dsa.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 = ".sig";int main(int argc, char* argv[]) { try { if(argc != 4) { cout << "Usage: dsa_sig 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 g = pop_bigint(pipe); BigInt p = pop_bigint(pipe); BigInt q = pop_bigint(pipe); BigInt x = pop_bigint(pipe); BigInt y = pop_bigint(pipe); DL_Group group(p, q, g); // this ordering makes little or no sense... DSA_PrivateKey dsakey(group, x, y); ifstream message(argv[2]); if(!message) { cout << "Couldn't read the message file." << endl; return 1; } std::string outfile = argv[2] + SUFFIX; ofstream sigfile(outfile.c_str()); if(!sigfile) { cout << "Couldn't write the signature to " << outfile << endl; return 1; } pipe.reset(); pipe.append(new PK_Signer_Filter(get_pk_signer(dsakey, "EMSA1(SHA-1)"))); pipe.append(new Base64_Encoder); pipe.start_msg(); message >> pipe; pipe.end_msg(); sigfile << pipe.read_all_as_string(2) << std::endl; } 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(); }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 + -