使用Crypto++ Base64编码器时避免换行

3

我正在尝试使用Crypto++生成一个Base64编码字符串的SHA512哈希值。

我的示例输入是:test123

Base64编码:dGVzdDEyMw==

Base64哈希的SHA512(期望):

f78fa0aa79abd53b8181c5d21bdeb882bf45cd462a6e6e1b5043417de1800626
ed2a51b1a56626e9b9558da66a2f609d31db76bd88e80afbb7b03cda518b207d

B64的SHA512(不是预期的):9f012fff26c89f2650f7446a37e80ba6466d69ffc77bb9ffc8c09ab779b24a23bb6a2f3c28512668ebca8628303ab5a31067d930cd1af60c745a2c34e5b4b1d2

SHA512计算:

byte *digest = new byte[CryptoPP::SHA512::DIGESTSIZE];
std::string encoded;
std::string test("test123");

CryptoPP::StringSource ss((byte*)test.data(), test.size(), true, new CryptoPP::Base64Encoder(new CryptoPP::StringSink(encoded))); // StringSource

// Calculate hash
CryptoPP::SHA512().CalculateDigest(digest, (byte*)encoded.data(), encoded.size());

如果我省略base64并直接计算SHA512,那么我会得到正确的哈希值。因此,计算不能完全错误。
但是为什么使用base64不起作用呢?
1个回答

4

SHA512 of B64 (correct):

f78fa0aa79abd53b8181c5d21bdeb882bf45cd462a6e6e1b5043417de1800626
ed2a51b1a56626e9b9558da66a2f609d31db76bd88e80afbb7b03cda518b207d

听起来计算哈希的工具产生了意外的结果。可能是由于换行符、缺少填充等原因。

我可以通过以下方式重现该问题。看起来是一个换行符的问题。

$ echo 'dGVzdDEyMw' | sha512sum
9c00af94b3dc300fab0fd1fdad7e9eeb20bb0bdff6e6c75d9072e241976b0cc8
56f2a1d355c35f29c3d354895565f971721f58cbb20f0608f57a882b0afb412c

$ echo -n 'dGVzdDEyMw' | sha512sum
c20144e3136f57d5aae2374aa48759911364bb44167fe642cc8b4da140396584
04ce9e2f3dfc9bd69d69cfbb449384e6ea5377c39a07fdb2c2920d78a2a56a80

$ echo  'dGVzdDEyMw==' | sha512sum
9f012fff26c89f2650f7446a37e80ba6466d69ffc77bb9ffc8c09ab779b24a23
bb6a2f3c28512668ebca8628303ab5a31067d930cd1af60c745a2c34e5b4b1d2

$ echo -n 'dGVzdDEyMw==' | sha512sum
f78fa0aa79abd53b8181c5d21bdeb882bf45cd462a6e6e1b5043417de1800626
ed2a51b1a56626e9b9558da66a2f609d31db76bd88e80afbb7b03cda518b207d

以下是Base64Encoder的构造函数。您可以在手册维基中找到文档。

Base64Encoder(BufferedTransformation *attachment = NULL,
              bool insertLineBreaks = true,
              int maxLineLength = 72)

您应该使用insertLineBreaks = false。可能类似这样:
StringSource ss((byte*)test.data(), test.size(), true,
    new Base64Encoder(new StringSink(encoded), false /* Newline */));

既然您正在使用管道,因此可以使用以下方法一次性完成操作。我展开了所有的new以帮助可视化数据从源到汇的流动。

SHA512 hash;
StringSource ss(test /* std::string */, true,
    new Base64Encoder(
        new HashFilter(hash,
            new StringSink(encoded)
        ),
    false /* Newline */)
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接