【发布时间】:2019-03-04 05:25:35
【问题描述】:
我正在我的一个项目中实施 Curve25519。我想我可以将它与 HMAC、CMAC 或其他算法结合起来进行签名和验证。问题是 Curve25519 没有生成相同的共享密钥。
我不太了解密码学,不知道是我做错了什么,还是我无法将 Curve25519 与 HMAC 结合起来。
这是我准备的测试代码。
#include "xed25519.h"
using CryptoPP::x25519;
#include "donna.h"
using CryptoPP::Donna::curve25519_mult;
using CryptoPP::Donna::ed25519_sign;
using CryptoPP::Donna::ed25519_sign_open;
using CryptoPP::Donna::ed25519_publickey;
#include "filters.h"
#include "osrng.h"
#include "cryptlib.h"
#include "files.h"
#include "hex.h"
#include "sha.h"
#include "hmac.h"
using namespace std;
static const int SECRET_KEYLENGTH=32;
static const int PRIVATE_KEYLENGTH=128;
static const int PUBLIC_KEYLENGTH=32;
#include <string>
#include <iostream>
int main(int argc, char* argv[])
{
using namespace CryptoPP;
AutoSeededRandomPool prng, prng2;
byte *aux ;// new byte[PRIVATE_KEYLENGTH];
byte privateKey[PUBLIC_KEYLENGTH];
byte publicKey[PUBLIC_KEYLENGTH];
// Node 1
x25519 x(privateKey, publicKey) ; //( const byte y[PUBLIC_KEYLENGTH],const byte x[SECRET_KEYLENGTH]
cout << "1- Generating private key " << endl;
aux = new byte;
x.GeneratePrivateKey(prng, privateKey);
Integer intPrvK(privateKey, sizeof(privateKey));
cout << "Private key created " << intPrvK << endl;
cout << "1- Generating public key " << endl;
//void GeneratePublicKey (RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
if(curve25519_mult(privateKey, publicKey) == 0 ){
Integer intPubK(publicKey, sizeof(publicKey));
cout << "1- Public key created " << intPubK << endl;
//cout << "1- The new public key is " << privateKey << endl;
}
else
cout << "curve25519_mult did not work " << endl;
//Node 2
byte privateKey2[PUBLIC_KEYLENGTH];
byte publicKey2[PUBLIC_KEYLENGTH];
x25519 y(privateKey2, publicKey2) ; //( const byte y[PUBLIC_KEYLENGTH],const byte x[SECRET_KEYLENGTH]
cout << "2- Generating private key " << endl;
aux = new byte;
y.GeneratePrivateKey(prng2, privateKey2);
Integer intPrvK2(privateKey2, sizeof(privateKey2));
cout << "2- Private key created " << intPrvK2 << endl;
cout << "2- Generating public key " << endl;
//void GeneratePublicKey (RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
if(curve25519_mult(privateKey2, publicKey2) == 0 ){
Integer intPubK2(publicKey2, sizeof(publicKey2));
cout << "2- Public key created " << intPubK2 << endl;
//cout << "2- The new public key is " << privateKey2 << endl;
}
else
cout << "2- curve25519_mult did not work " << endl;
cout << "\nGenerations of shared keys" << endl;
/*int curve25519_mult ( byte sharedKey[32],
const byte secretKey[32],
const byte othersKey[32]
) */
byte sharedKey1_2[PUBLIC_KEYLENGTH];
byte sharedKey2_1[PUBLIC_KEYLENGTH];
if( curve25519_mult(sharedKey1_2, privateKey, publicKey2) == 0){
Integer intSharedKey1_2(sharedKey1_2, sizeof(sharedKey1_2));
cout << "1- Shared key created " << intSharedKey1_2 << endl;
}
if( curve25519_mult(sharedKey2_1, privateKey2, publicKey) == 0){
Integer intSharedKey2_1(sharedKey2_1, sizeof(sharedKey2_1));
cout << "2- Shared key created " << intSharedKey2_1 << endl;
}
// We have two keys each.
string plain = "\n\nHMAC Test";
string mac, encoded;
/*********************************\
\*********************************/
cout << "plain text: " << plain << endl;
/*********************************\
\*********************************/
try
{
HMAC< SHA256 > hmac(sharedKey1_2, PUBLIC_KEYLENGTH);
StringSource ss2(plain, true,
new HashFilter(hmac,
new StringSink(mac)
) // HashFilter
); // StringSource
}
catch(const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
exit(1);
}
/*********************************\
\*********************************/
// Pretty print
encoded.clear();
StringSource ss3(mac, true,
new HexEncoder(
new StringSink(encoded)
) // HexEncoder
); // StringSource
cout << "hmac: " << encoded << endl;
try
{
HMAC< SHA256 > hmac2(sharedKey2_1, PUBLIC_KEYLENGTH);
const int flags = HashVerificationFilter::THROW_EXCEPTION | HashVerificationFilter::HASH_AT_END;
StringSource(plain + mac, true,
new HashVerificationFilter(hmac2, NULL, flags)
); // StringSource
cout << "Verified message" << endl;
}
catch(const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
}
return 0;
}
编辑:这是这段代码的输出:
1- Generating private key
Private key created 3951427468589058657788500055898583055730859037456996206614247149081707227760.
1- Generating public key
1- Public key created 2713877106980505211026290261997698325438191786766062178625865092937394618368.
2- Generating private key
2- Private key created 58089620826126204922773651760985512282935010454438059044416143831910823682427.
2- Generating public key
2- Public key created 1185077373537344710091841384487531087158005785833397747712.
Generations of shared keys
1- Shared key created 32717475549536125870454478996763331991259932599267432219938737089203052157444.
2- Shared key created 83438083910146518364399797164490155462911710345063602550172142504835353991253.
plain text:
HMAC Test
hmac: 27C84FED802319639DF86D36E43090666D6CB20F556778B90819087BC55C2249
HashVerificationFilter: message hash or MAC not valid
我希望你们中的任何人都可以向我解释。
提前致谢!!
【问题讨论】:
-
请在代码之外解释您尝试实现的协议以及失败的位置和方式。调试加密通常是以十六进制打印并比较内容。如果 HMAC 的输入值不同,那么显然是有问题的。然后,您将不得不使用更多的打印语句来追溯差异的来源。
-
代码中没有使用该密钥长度。无论如何,它来自crypto++中的一个例子。尽管我还不知道我没有获得正确的共享密钥的方式,但我得到了与您的实现一起使用的代码。也许是因为我没有使用同意部分。
-
@Ruben - “我让代码工作了......” - 你应该发布一个答案,然后接受你自己的答案。它将使未来的游客受益。另见How does accepting an answer work?
标签: c++ cryptography hmac crypto++ elliptic-curve