无法使用 C 样式函数调用验证签名
Cannot verify signature using C-style function calls
以下打印失败,我不明白为什么:
#include <cryptopp/eccrypto.h>
#include <cryptopp/oids.h>
#include <cryptopp/osrng.h>
#include <iostream>
using namespace std;
using namespace CryptoPP;
int main() {
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::PrivateKey private_key;
ECDSA<ECP, SHA256>::PublicKey public_key;
private_key.Initialize( prng, ASN1::secp160r1() );
private_key.MakePublicKey(public_key);
ECDSA<ECP, SHA256>::Signer signer(private_key);
ECDSA<ECP, SHA256>::Verifier verifier(public_key);
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
string signature(signer.MaxSignatureLength(), 0);
string message = "asdf";
auto signature_length = signer.SignMessage(
prng, (const byte*)message.data(),
message.size(), (byte*)signature.data());
signature.resize(signature_length);
bool verified = verifier.VerifyMessage(
(const byte*)message.data(), message.size(),
(const byte*)signature.data(), signature.size());
if (verified)
cout << "PASS" << endl;
else
cout << "FAIL" << endl;
}
它遵循 crypto++ wiki 中的说明:https://www.cryptopp.com/wiki/ECDSA#Message_Signing 并使用从用于签署同一消息的私有派生的 public 密钥进行验证。我应该切换到过滤器吗?
The following prints FAIL and I cannot understand why:
你很接近。查看 wiki 页面有一些问题。首先,这是未定义的行为(已在 wiki 上修复):
auto signature_length = signer.SignMessage(
prng, (const byte*)message.data(),
message.size(), (byte*)signature.data());
要获得 non-const 指针,您需要这个(但这不是问题的原因):
auto signature_length = signer.SignMessage(
prng, (const byte*)&message[0],
message.size(), (byte*)&signature[0]);
其次,当您调用 Initialize
两次时,您会破坏旧配置。 "Whack" 表示您生成新参数。实际上你覆盖了另一个私钥:
private_key.Initialize( prng, ASN1::secp160r1() );
...
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
不是很明显,但是 Initialize
取一个 prng
生成一个新的密钥。您想要 不 的 Initialize
prng
:
private_key.Initialize( prng, ASN1::secp160r1() );
...
signer.AccessKey().Initialize(private_key);
三、页面不清楚如何在Signers/Verifiers和PublicKey/PrivateKey之间移动。为了便于说明,这里有一些其他的方法:
cryptopp $ cat test.cxx
#include "eccrypto.h"
#include "oids.h"
#include "osrng.h"
#include <string>
#include <iostream>
int main()
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::Signer signer;
ECDSA<ECP, SHA256>::Verifier verifier;
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
signer.AccessKey().MakePublicKey(verifier.AccessKey());
std::string signature(signer.MaxSignatureLength(), 0);
std::string message = "asdf";
auto signature_length = signer.SignMessage(
prng, (const byte*)&message[0],
message.size(), (byte*)&signature[0]);
signature.resize(signature_length);
bool verified = verifier.VerifyMessage(
(const byte*)&message[0], message.size(),
(const byte*)&signature[0], signature.size());
if (verified)
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
return 0;
}
我在 Crypto++ 目录下工作,所以包含和命令行有点不同:
cryptopp$ g++ -I . test.cxx ./libcryptopp.a -o test.exe
cryptopp$ ./test.exe
PASS
如果您想同时使用 Signers/Verifiers 和 PublicKey/PrivateKey,请尝试以下操作:
cryptopp$ cat test.cxx
#include "eccrypto.h"
#include "oids.h"
#include "osrng.h"
#include <string>
#include <iostream>
int main()
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::Signer signer;
ECDSA<ECP, SHA256>::Verifier verifier;
ECDSA<ECP, SHA256>::PrivateKey& sKey = signer.AccessKey();
sKey.Initialize(prng, ASN1::secp160r1());
ECDSA<ECP, SHA256>::PublicKey& pKey = verifier.AccessKey();
sKey.MakePublicKey(pKey);
std::string signature(signer.MaxSignatureLength(), 0);
std::string message = "asdf";
auto signature_length = signer.SignMessage(
prng, (const byte*)&message[0],
message.size(), (byte*)&signature[0]);
signature.resize(signature_length);
bool verified = verifier.VerifyMessage(
(const byte*)&message[0], message.size(),
(const byte*)&signature[0], signature.size());
if (verified)
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
return 0;
}
这看起来有点不寻常:
ECDSA<ECP, SHA256>::Signer signer;
...
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
通常使用 {secp160r1, SHA1}
或 {secp256k1, SHA256}
。这维护了整个系统的Security Levels。当您使用 {secp160r1, SHA256}
时,您会将安全级别降低到大约 80 位,因为 secp160r1
.
以下打印失败,我不明白为什么:
#include <cryptopp/eccrypto.h>
#include <cryptopp/oids.h>
#include <cryptopp/osrng.h>
#include <iostream>
using namespace std;
using namespace CryptoPP;
int main() {
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::PrivateKey private_key;
ECDSA<ECP, SHA256>::PublicKey public_key;
private_key.Initialize( prng, ASN1::secp160r1() );
private_key.MakePublicKey(public_key);
ECDSA<ECP, SHA256>::Signer signer(private_key);
ECDSA<ECP, SHA256>::Verifier verifier(public_key);
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
string signature(signer.MaxSignatureLength(), 0);
string message = "asdf";
auto signature_length = signer.SignMessage(
prng, (const byte*)message.data(),
message.size(), (byte*)signature.data());
signature.resize(signature_length);
bool verified = verifier.VerifyMessage(
(const byte*)message.data(), message.size(),
(const byte*)signature.data(), signature.size());
if (verified)
cout << "PASS" << endl;
else
cout << "FAIL" << endl;
}
它遵循 crypto++ wiki 中的说明:https://www.cryptopp.com/wiki/ECDSA#Message_Signing 并使用从用于签署同一消息的私有派生的 public 密钥进行验证。我应该切换到过滤器吗?
The following prints FAIL and I cannot understand why:
你很接近。查看 wiki 页面有一些问题。首先,这是未定义的行为(已在 wiki 上修复):
auto signature_length = signer.SignMessage(
prng, (const byte*)message.data(),
message.size(), (byte*)signature.data());
要获得 non-const 指针,您需要这个(但这不是问题的原因):
auto signature_length = signer.SignMessage(
prng, (const byte*)&message[0],
message.size(), (byte*)&signature[0]);
其次,当您调用 Initialize
两次时,您会破坏旧配置。 "Whack" 表示您生成新参数。实际上你覆盖了另一个私钥:
private_key.Initialize( prng, ASN1::secp160r1() );
...
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
不是很明显,但是 Initialize
取一个 prng
生成一个新的密钥。您想要 不 的 Initialize
prng
:
private_key.Initialize( prng, ASN1::secp160r1() );
...
signer.AccessKey().Initialize(private_key);
三、页面不清楚如何在Signers/Verifiers和PublicKey/PrivateKey之间移动。为了便于说明,这里有一些其他的方法:
cryptopp $ cat test.cxx
#include "eccrypto.h"
#include "oids.h"
#include "osrng.h"
#include <string>
#include <iostream>
int main()
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::Signer signer;
ECDSA<ECP, SHA256>::Verifier verifier;
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
signer.AccessKey().MakePublicKey(verifier.AccessKey());
std::string signature(signer.MaxSignatureLength(), 0);
std::string message = "asdf";
auto signature_length = signer.SignMessage(
prng, (const byte*)&message[0],
message.size(), (byte*)&signature[0]);
signature.resize(signature_length);
bool verified = verifier.VerifyMessage(
(const byte*)&message[0], message.size(),
(const byte*)&signature[0], signature.size());
if (verified)
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
return 0;
}
我在 Crypto++ 目录下工作,所以包含和命令行有点不同:
cryptopp$ g++ -I . test.cxx ./libcryptopp.a -o test.exe
cryptopp$ ./test.exe
PASS
如果您想同时使用 Signers/Verifiers 和 PublicKey/PrivateKey,请尝试以下操作:
cryptopp$ cat test.cxx
#include "eccrypto.h"
#include "oids.h"
#include "osrng.h"
#include <string>
#include <iostream>
int main()
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::Signer signer;
ECDSA<ECP, SHA256>::Verifier verifier;
ECDSA<ECP, SHA256>::PrivateKey& sKey = signer.AccessKey();
sKey.Initialize(prng, ASN1::secp160r1());
ECDSA<ECP, SHA256>::PublicKey& pKey = verifier.AccessKey();
sKey.MakePublicKey(pKey);
std::string signature(signer.MaxSignatureLength(), 0);
std::string message = "asdf";
auto signature_length = signer.SignMessage(
prng, (const byte*)&message[0],
message.size(), (byte*)&signature[0]);
signature.resize(signature_length);
bool verified = verifier.VerifyMessage(
(const byte*)&message[0], message.size(),
(const byte*)&signature[0], signature.size());
if (verified)
std::cout << "PASS" << std::endl;
else
std::cout << "FAIL" << std::endl;
return 0;
}
这看起来有点不寻常:
ECDSA<ECP, SHA256>::Signer signer;
...
signer.AccessKey().Initialize(prng, ASN1::secp160r1());
通常使用 {secp160r1, SHA1}
或 {secp256k1, SHA256}
。这维护了整个系统的Security Levels。当您使用 {secp160r1, SHA256}
时,您会将安全级别降低到大约 80 位,因为 secp160r1
.