【发布时间】:2014-01-12 19:58:04
【问题描述】:
我使用 Crypto++ 使用 ECDSA 制作了 Signer/Checker 机制。
问题是当我想检查签名时,它不适用于验证功能。
您能否建议我一种更手动的方式来验证签名?
【问题讨论】:
-
请发布一些您正在使用的代码。尽量减少测试用例。
标签: digital-signature crypto++ ecdsa
我使用 Crypto++ 使用 ECDSA 制作了 Signer/Checker 机制。
问题是当我想检查签名时,它不适用于验证功能。
您能否建议我一种更手动的方式来验证签名?
【问题讨论】:
标签: digital-signature crypto++ ecdsa
如何在没有验证功能的情况下使用 Crypto++ 验证 ECDSA 签名?
我不确定如果没有验证功能,您将如何验证代码。我可能不明白这个问题。
以防万一,以下是 Crypto++ 实现其验证码的方式。
首先,ECDSA 是一个DL_Algorithm_ECDSA(来自eccrypto.h):
//! ECDSA algorithm
template <class EC>
class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
{
public:
static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
};
...
template <class EC, class H>
struct ECDSA :
public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>,
DL_SignatureMessageEncodingMethod_DSA, H>
{
};
接下来,这里是来自DL_Algorithm_GDSA in gfcrypt.h 的验证函数:
bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey,
const Integer &e, const Integer &r, const Integer &s) const
{
const Integer &q = params.GetSubgroupOrder();
if (r>=q || r<1 || s>=q || s<1)
return false;
Integer w = s.InverseMod(q);
Integer u1 = (e * w) % q;
Integer u2 = (r * w) % q;
return r == params.ConvertElementToInteger(
publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
}
下面的代码使用VerifyMessage,它在cryptolib.h中声明的PK_Verifier的一部分:
virtual bool VerifyMessage(const byte *message, size_t messageLen,
const byte *signature, size_t signatureLength) const;
PK_Verifier 是 ECDSA、NR 和 RSASS 等对象用来公开一致接口的“主”基类。
ECDSA、NR 和 RSASS 等对象通过 DL_SS 连接到 PK_Verifier:
template <class EC, class H>
struct ECDSA :
public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
{
};
最后,这是DL_SS 与PK_Verifier 的关系(来自pubkey.h):
//! Discrete Log Based Signature Scheme
template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
class DL_SS : public KEYS
{
typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
...
//! implements PK_Signer interface
typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
//! implements PK_Verifier interface
typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
};
问题是当我想检查签名时,它不适用于验证功能。
Crypto++ wiki 上有很多可用的代码。对于 ECDSA,请参阅 Elliptic Curve Digital Signature Algorithm。下面是一个签名验证样本,取自 wiki。
签名
AutoSeededRandomPool prng;
ECDSA<ECP, SHA1>::PrivateKey privateKey;
privateKey.Load(...);
privateKey.Validate(prng, 3);
ECDSA<ECP, SHA1>::Signer signer(privateKey);
string message = "Do or do not. There is no try.";
// Determine maximum size, allocate a string with the maximum size
size_t siglen = signer.MaxSignatureLength();
string signature(siglen, 0x00);
// Sign, and trim signature to actual size
siglen = signer.SignMessage( prng, message.data(), message.size(), signature.data() );
signature.resize(siglen);
验证
AutoSeededRandomPool prng;
ECDSA<ECP, SHA1>::PublicKey publicKey;
publicKey.Load(...);
publicKey.Validate(prng, 3);
ECDSA<ECP, SHA1>::Verifier verifier(publicKey);
bool result = verifier.VerifyMessage( message.data(), message.size(), signature.data(), signature.size() );
if(result)
cout << "Verified signature on message" << endl;
else
cerr << "Failed to verify signature on message" << endl;
【讨论】:
test.cpp 中做了类似的事情。请参阅选项mac_dll 的代码。简而言之,mac_dll 打开可执行文件,使用HMAC 对代码进行校验和,然后将预期的指纹嵌入回可执行文件中以检测篡改。在运行时,可执行文件验证校验和代码上的签名。 mac_dll 存在是因为 FIPS 140-2 要求。另见Dynamic TEXT Section Image Verification。