I am writing a project about the AODV routing protocol in MANETs (mobile ad hoc networks) and one of things I am aiming to do is to add a digital signature to a field in one of the protocol's packets.
I am using NS3 to simulate the network which is based on C++. For the signing, I am using Crypto++'s RSA library. Basically, a node generates a public and private key pair to sign the packet, includes its public key in the packet, then sends it to another node. The receiving node then uses the public key provided in the packet to verify the signature. The public key in the packet is encoded as a hex string with std::string data type.
I have already confirmed that the public key is correct and the problem solely lies on decoding the public key string from hex format.
These are the functions I use to generate key pairs, sign, and verify
(I got these from http://marko-editor.com/articles/cryptopp_sign_string/):
struct KeyPairHex {
std::string publicKey;
std::string privateKey;
};
KeyPairHex
RoutingProtocol::RsaGenerateHexKeyPair(unsigned int aKeySize) {
KeyPairHex keyPair;
// PGP Random Pool-like generator
AutoSeededRandomPool rng;
// generate keys
RSA::PrivateKey privateKey;
privateKey.GenerateRandomWithKeySize(rng, aKeySize);
RSA::PublicKey publicKey(privateKey);
// save keys
publicKey.Save( HexEncoder(
new StringSink(keyPair.publicKey)).Ref());
privateKey.Save(HexEncoder(
new StringSink(keyPair.privateKey)).Ref());
return keyPair;
}
std::string
RoutingProtocol::RsaSignString(const std::string &aPrivateKeyStrHex,
const std::string &aMessage) {
// decode and load private key (using pipeline)
RSA::PrivateKey privateKey;
privateKey.Load(StringSource(aPrivateKeyStrHex, true,
new HexDecoder()).Ref());
// sign message
std::string signature;
RSASS::Signer signer(privateKey);
AutoSeededRandomPool rng;
StringSource ss(aMessage, true,
new SignerFilter(rng, signer,
new HexEncoder(
new StringSink(signature))));
return signature;
}
bool
RoutingProtocol::RsaVerifyString(const std::string &aPublicKeyStrHex,
const std::string &aMessage,
const std::string &aSignatureStrHex) {
// decode and load public key (using pipeline)
RSA::PublicKey publicKey;
publicKey.Load(StringSource(aPublicKeyStrHex, true,
new HexDecoder()).Ref());
// decode signature
std::string decodedSignature;
StringSource ss(aSignatureStrHex, true,
new HexDecoder(
new StringSink(decodedSignature)));
// verify message
bool result = false;
RSASS::Verifier verifier(publicKey);
StringSource ss2(decodedSignature + aMessage, true,
new SignatureVerificationFilter(verifier,
new ArraySink((byte*)&result, sizeof(result))));
return result;
}
I am using a keysize of 384. Here is the public key:
304A300D06092A864886F70D01010105000339003036023100CC112A0E007C6329F813BC96498AFE
DF580EE4F708C2A923F6C6257FA4CC5FE2BA711C75CDE02036839E67C9B62720B3020111
There is no problem with signing the message. However, when loading the key from the string I keep getting an error.
The error I am getting is:
terminate called after throwing instance of 'BerDecodeErr' what(): BER decode error