繁体   English   中英

如何通过 Crypto++ 和 RSA 签署文件

[英]How to sign a file via Crypto++ and RSA

我正在尝试使用以下 function 使用我的私钥签署文件:

void Signer::SignFile(const std::string& file)
{
    RSASS<PSSR, Whirlpool>::Signer signer(rsaPrivate);

    // Encrypt and write
    FileSource ss1(file.c_str(), true,
        new SignerFilter(rng, signer,
                new FileSink(file.c_str(), true)
            , true));
}

结果,我的目标文件被签名覆盖。 为什么会这样? 显然我想将 append 放到文件中,这就是为什么我还为“putMessage”添加了一个额外的“true”参数。

FileSource ss1(file.c_str(), true, new SignerFilter(rng, signer, new FileSink(file.c_str(), true), true));

我[个人]从未见过有人使用相同的文件作为源和接收器。 通常文件数据和签名是分开的,就像分离的签名一样。

看起来一个文件/两个流是实现定义的: C++ read and write to same file using different streams 我想您应该期望在不同平台上出现看似随机的结果。

结果,我的目标文件被签名覆盖。 为什么会这样?

FileSink打开std::ios_base::tunc 另请参阅 Crypto++ wiki 上的FileSink

你可能应该做这样的事情。 它将签名保存到中间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));

显然我想将 append 放到文件中,这就是为什么......

此外,因为您使用的是 PSSR,所以不需要原始消息。 PSSR 是“具有恢复的概率签名方案” 该消息包含在带有掩码 function 的签名中。

您需要带有 SSA 方案的原始消息。 SSA 是“带有附录的签名方案” 在 SSA 方案中,您需要同时提供原始消息和签名。


(来自评论)这是一个使用带有附录(SSA)的签名方案的示例。 它还直接使用std::iftreamstd::ofstream ,因此FileSourceFileSink可以按预期工作。 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|

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM