FileSource ss1(file.c_str(), true,
new SignerFilter(rng, signer,
new FileSink(file.c_str(), true), true));
Я [лично] никогда не видел, чтобы кто-то использовал один и тот же файл в качестве источника и приемника. Обычно данные файла и подпись разделяются, как с отдельной подписью.
Похоже, один файл / два потока определяется реализацией: C ++ читает и записывает в один и тот же файл, используя разные потоки . Полагаю, вам следует ожидать, казалось бы, случайных результатов на разных платформах.
В результате мой целевой файл будет перезаписан подписью. Почему это происходит?
FileSink
открывается с std::ios_base::tunc
. Также см. FileSink на вики-сайте Crypto ++.
Возможно, вам следует сделать что-то подобное. Сохраняет подпись в промежуточном ByteQueue
, а затем записывает очередь в файл после закрытия файла.
#include "cryptlib.h"
#include "filters.h"
#include "osrng.h"
#include "files.h"
#include "pssr.h"
#include "rsa.h"
#include "whrlpool.h"
#include <iostream>
#include <fstream>
#include <string>
int main(int argc, char* argv[])
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
std::string fname("test.bin");
///// Create test message /////
{
std::string msg("Yoda said, Do or do not. There is no try.");
std::ofstream out(fname.c_str());
out.write(msg.data(), msg.size());
}
///// Generate a key /////
RSASS<PSSR, Whirlpool>::Signer signer;
signer.AccessKey().GenerateRandomWithKeySize(prng, 2048);
///// Sign the message /////
ByteQueue queue;
{
FileSource source(fname.c_str(), true,
new SignerFilter(prng, signer,
new Redirector(queue)));
}
///// Append the signature /////
{
std::ofstream out(fname.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::app);
queue.TransferTo(FileSink(out).Ref());
}
///// Create a verifier /////
RSASS<PSSR, Whirlpool>::Verifier verifier(signer);
///// Verify the message /////
{
FileSource source(fname.c_str(), true,
new SignatureVerificationFilter(verifier, NULLPTR,
SignatureVerificationFilter::THROW_EXCEPTION));
}
std::cout << "Verified signature on message" << std::endl;
return 0;
}
Не вылетает и добавляет сообщение, как и ожидалось:
$ ./test.exe
Verified signature on message
$ hexdump -C test.bin
00000000 59 6f 64 61 20 73 61 69 64 2c 20 44 6f 20 6f 72 |Yoda said, Do or|
00000010 20 64 6f 20 6e 6f 74 2e 20 54 68 65 72 65 20 69 | do not. There i|
00000020 73 20 6e 6f 20 74 72 79 2e 19 f2 1c 8f f9 cb 2f |s no try......./|
00000030 f2 38 9f a8 3b a9 0b 8b 62 25 56 a8 ea 81 7e 60 |.8..;...b%V...~`|
00000040 22 55 38 ce 79 7f 32 95 a5 1a 75 c1 80 ad b2 c2 |"U8.y.2...u.....|
00000050 6f ce a5 f7 bd 4b d3 3f e4 b3 69 00 21 60 d7 09 |o....K.?..i.!`..|
00000060 a8 71 9b 5f 41 d6 66 b1 80 f1 de 00 26 19 34 01 |.q._A.f.....&.4.|
00000070 b3 65 1b 78 e2 32 71 be bc 07 25 78 36 6b 56 4e |.e.x.2q...%x6kVN|
00000080 26 4e 12 9e a8 bb 72 86 ee 0d 70 b2 f1 bd a3 2c |&N....r...p....,|
00000090 14 fd 12 61 35 98 4a 80 9f ee 3c 31 d3 70 26 0f |...a5.J...<1.p&.|
000000a0 73 a0 5d 36 ef 96 56 65 f8 ac 3a fb 44 c3 04 76 |s.]6..Ve..:.D..v|
000000b0 e5 2f ae 92 84 be 40 34 f6 4b b8 84 aa bd 67 74 |./....@4.K....gt|
000000c0 05 43 91 d2 e6 b1 50 dd 6d 64 47 cc 3e 3c 3a 9d |.C....P.mdG.><:.|
000000d0 67 ff 4f 38 c1 a5 a6 d5 92 45 bc 2d ff 96 30 3a |g.O8.....E.-..0:|
000000e0 1d 3a 42 4f 8c 13 2d 4c 3f e9 ad 08 a6 b3 5e fa |.:BO..-L?.....^.|
000000f0 46 08 24 17 43 ce ed ec f7 1a 38 62 e7 bf 42 93 |F.$.C.....8b..B.|
00000100 84 44 b6 05 22 9e e3 bd 80 a6 08 b0 34 d0 a4 89 |.D..".......4...|
00000110 78 48 20 7f 7b 33 1c 51 9d 48 b5 b7 f7 de 2f dd |xH .{3.Q.H..../.|
00000120 d7 74 7b af 04 cd 92 fc 1c |.t{......|
Я не смог заставить это работать. Я почти уверен, что это тупик.
std::fstream inout(fname.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary | std::ios_base::app);
FileSource fs(inout, true,
new SignerFilter(prng, signer,
new FileSink(inout), true));
Очевидно, я бы хотел добавить его в файл, поэтому ...
Кроме того, поскольку вы используете PSSR, вам не нужно исходное сообщение. PSSR является «вероятностной схемой подписи с восстановлением» . Сообщение включается в подпись с помощью функции маски.
Вам понадобится исходное сообщение со схемой SSA. SSA "схема подписи с приложением" . В схеме SSA вам необходимо предоставить как исходное сообщение, так и подпись.
(из комментариев) Вот пример, в котором используется Схема подписи с Приложением (SSA). Он также использует std::iftream
и std::ofstream
напрямую, поэтому FileSource
и FileSink
работают, как вы ожидаете. std::ofstream
включает std::ios_base::app
, поэтому подпись добавляется.
#include "cryptlib.h"
#include "filters.h"
#include "osrng.h"
#include "files.h"
#include "oaep.h"
#include "rsa.h"
#include "sha.h"
#include <iostream>
#include <fstream>
#include <string>
int main(int argc, char* argv[])
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
std::string fname("test.bin");
///// Create test message /////
{
std::string msg("Yoda said, Do or do not. There is no try.");
std::ofstream out(fname.c_str());
out.write(msg.data(), msg.size());
}
///// Generate a key /////
RSASS<PKCS1v15, SHA256>::Signer signer;
signer.AccessKey().GenerateRandomWithKeySize(prng, 2048);
{
///// Create fstreams for input and output /////
std::ifstream fin(fname.c_str(), std::ios_base::in | std::ios_base::binary);
std::ofstream fout(fname.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::app);
///// Sign the message /////
FileSource source(fin, true,
new SignerFilter(prng, signer,
new FileSink(fout)));
}
///// Create a verifier /////
RSASS<PKCS1v15, SHA256>::Verifier verifier(signer);
///// Verify the message /////
{
FileSource source(fname.c_str(), true,
new SignatureVerificationFilter(verifier, NULLPTR,
SignatureVerificationFilter::THROW_EXCEPTION));
}
std::cout << "Verified signature on message" << std::endl;
return 0;
}
А затем:
$ ./test.exe
Verified signature on message
$ hexdump -C test.bin
00000000 59 6f 64 61 20 73 61 69 64 2c 20 44 6f 20 6f 72 |Yoda said, Do or|
00000010 20 64 6f 20 6e 6f 74 2e 20 54 68 65 72 65 20 69 | do not. There i|
00000020 73 20 6e 6f 20 74 72 79 2e c7 b3 6f 84 1d fd bf |s no try...o....|
00000030 c7 c8 38 7c 89 b1 f3 42 ee 5e f8 10 de a8 01 7f |..8|...B.^......|
00000040 7f a5 24 3d 27 7e 55 16 bc 80 8b 21 21 75 3d ed |..$='~U....!!u=.|
00000050 41 05 84 b1 3d bf d3 ae 3a 2f a8 81 7a e7 e4 ae |A...=...:/..z...|
00000060 50 d7 9b 25 04 17 a6 a3 1d 12 e2 8e cd 7a 02 42 |P..%.........z.B|
00000070 91 c0 d7 fc 43 09 94 a2 66 d9 67 95 55 5e dc 8c |....C...f.g.U^..|
00000080 eb bc 20 af e8 5c d4 63 05 d4 2c 48 57 6d f1 fe |.. ..\.c..,HWm..|
00000090 26 16 80 c3 41 11 58 8e 8d b0 cb 48 95 b9 ed 94 |&...A.X....H....|
000000a0 84 cc 86 0f a4 7e a3 6a ff 0d 0d 24 17 82 13 94 |.....~.j...$....|
000000b0 54 cb 8a ca 04 1e 65 18 c3 ab a2 3f 4d 44 de 42 |T.....e....?MD.B|
000000c0 32 07 29 e4 95 83 cc ff 39 85 08 bf d5 61 46 db |2.).....9....aF.|
000000d0 e0 96 d6 69 25 b9 ce 1e 3e bc 63 81 e5 16 bd 12 |...i%...>.c.....|
000000e0 a0 78 02 19 60 96 80 36 7d a5 79 be 0f 45 54 f4 |.x..`..6}.y..ET.|
000000f0 92 af f0 d8 74 65 7d 45 98 c7 bb 7f 6e 9b e3 cd |....te}E....n...|
00000100 c0 60 91 0f 78 aa 7c 77 a7 f5 4e 7d 6e ed e1 4c |.`..x.|w..N}n..L|
00000110 8e 5e 96 ac cd 30 16 e0 2d be 9e 2d 68 d4 25 46 |.^...0..-..-h.%F|
00000120 86 77 87 be 68 ef 06 26 55 |.w..h..&U|