Hi Jeff, Thank you very much for the prompt reply. Actually I also tried the example provided in https://www.codeproject.com/Articles/25590/Cryptographic-Interoperability-Digital-Signatures, still facing the same problem. I am sure that the P1316 signature is not empty.
I am sorry that I am not very familiar with the ECDSA and hence not able to debug the code of DSAConvertSignatureFormat... Thank you very much in advance for your insights! Best Regards, Jeffrey Walton於 2018年7月18日星期三 UTC+8下午2時42分50秒寫道: > > > > On Wednesday, July 18, 2018 at 2:40:18 AM UTC-4, Jeffrey Walton wrote: >> >> >> On Wednesday, July 18, 2018 at 12:45:45 AM UTC-4, 王祥 wrote: >>> >>> Hi all, >>> I found that the default format is P1363. >>> Since I am signing the message using crypto++ ecdsa, and verify the >>> signature with Go, I need to change the signature format from P1363 to DER. >>> ... >>> >>> However, the length below is 0, does anybody know if there is something >>> wrong? >>> // Determine size of required buffer >>> auto length = DSAConvertSignatureFormat(NULL, 0, DSA_DER, >>> (byte*)signatureP1363.c_str(), signatureP1363.size(), >>> DSA_P1363); >>> >> >> You should probably show the data in signatureP1363 . It sounds like >> signatureP1363 is empty. >> > > By the way, here is the source code to DSAConvertSignatureFormat: > https://github.com/weidai11/cryptopp/blob/master/dsa.cpp > > Jeff > -- You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users. --- You received this message because you are subscribed to the Google Groups "Crypto++ Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
// CryptoPP.cpp
//
#include "stdafx.h"
#include <dsa.h>
using CryptoPP::DSA;
using CryptoPP::DSA_DER;
using CryptoPP::DSA_P1363;
#include <pubkey.h>
using CryptoPP::PrivateKey;
using CryptoPP::PublicKey;
#include <osrng.h>
using CryptoPP::AutoSeededRandomPool;
#include <files.h>
using CryptoPP::FileSource;
using CryptoPP::FileSink;
using CryptoPP::StringSource;
using CryptoPP::StringSink;
bool CreateDSAKeys();
bool SignDSAMessage();
bool VerifyDSAMessage();
int main(int argc, char* argv[])
{
CreateDSAKeys();
SignDSAMessage();
VerifyDSAMessage();
return 0;
}
bool CreateDSAKeys()
{
AutoSeededRandomPool prng;
try
{
// Crypto++ Key Generation
DSA::Signer signer;
PrivateKey& privateKey = signer.AccessPrivateKey();
privateKey.GenerateRandom( prng );
DSA::Verifier verifier( signer );
PublicKey& publicKey = verifier.AccessPublicKey();
// Crypto++ Save Keys
privateKey.Save(FileSink("private.dsa.cpp.key"));
publicKey.Save(FileSink("public.dsa.cpp.key"));
}
catch( CryptoPP::Exception& ex )
{
cerr << "Caught Error:" << endl;
cerr << " " << ex.what() << endl;
return false;
}
catch( std::exception& ex )
{
cerr << "Caught Error:" << endl;
cerr << " " << ex.what() << endl;
return false;
}
return true;
}
bool VerifyDSAMessage()
{
try
{
//
// Crypto++ Load the Pubic Key
//
DSA::Verifier verifier;
PublicKey& publicKey = verifier.AccessPublicKey();
publicKey.Load(FileSource("public.dsa.cpp.key", true));
// publicKey.Load(FileSource("public.dsa.java.key", true));
// publicKey.Load(FileSource("public.dsa.cs.key", true));
//
// Retrieve the Message and the Signature on Message
//
string message, signature;
// C++
FileSource( "dsa.cpp.msg", true, new StringSink( message ) );
FileSource( "dsa.cpp.sig", true, new StringSink( signature ) );
// Java
// FileSource( "dsa.java.msg", true, new StringSink( message ) );
// FileSource( "dsa.java.sig", true, new StringSink( signature ) );
// C#
// FileSource( "dsa.cs.msg", true, new StringSink( message ) );
// FileSource( "dsa.cs.sig", true, new StringSink( signature ) );
//*
// --- Begin Java Specific Conversion ---
//
// Convert: DER -> P1363
//
// Java is DER Encoded Sequence.
// Crypto++ is P1363 format.
{
// From dsa.h: If toFormat == DSA_P1363,
// bufferSize must equal publicKey.SignatureLength()
size_t length = verifier.SignatureLength();
// A buffer for the conversion
byte* buffer = new byte[ length ];
// Shit or Go Blind. You make the choice.
if( !buffer ) { return false; }
// Reuse length
length = CryptoPP::DSAConvertSignatureFormat(
buffer, length, DSA_P1363, (const byte*)signature.c_str(),
signature.length(), DSA_DER );
// Reinitialize signature so that it can be used
// in the verifier below with minimal effort
signature = string( (const char*)buffer, length );
delete[] buffer;
}
// --- End Java Specific Conversion ---
//*/
//
// Verify the Signature on the Message
//
bool result = verifier.VerifyMessage(
(const byte*)message.c_str(), message.length(),
(const byte*)signature.c_str(), signature.length() );
if( result )
{
cout << "Signature on Message verified" << endl;
}
else
{
cerr << "Signature on Message not verified" << endl;
return false;
}
//
// Convert the Message
//
int nChars = MultiByteToWideChar( CP_UTF8, 0,
message.c_str(), -1, NULL, NULL );
wchar_t* p = new wchar_t[ nChars ];
if( !p ) { return false; }
MultiByteToWideChar( CP_UTF8, 0, message.c_str(), -1, p, nChars );
wstring wide( p );
delete[] p;
}
catch( CryptoPP::Exception& ex )
{
cerr << "Caught Error:" << endl;
cerr << " " << ex.what() << endl;
return false;
}
catch( std::exception& ex )
{
cerr << "Caught Error:" << endl;
cerr << " " << ex.what() << endl;
return false;
}
return true;
}
bool SignDSAMessage()
{
try
{
//
// Crypto++ Load Private Key
//
DSA::Signer signer;
PrivateKey& privateKey = signer.AccessPrivateKey();
privateKey.Load(FileSource("private.dsa.cpp.key", true));
// Convert the Message
wstring wide = L"Crypto Interop: \u9aa8";
int nChars = WideCharToMultiByte( CP_UTF8, 0,
wide.c_str(), -1, NULL, 0, NULL, FALSE );
char* p = new char[ nChars ];
if( !p ) { return false; }
nChars = WideCharToMultiByte( CP_UTF8, 0,
wide.c_str(), -1, p, nChars, NULL, FALSE );
string narrow( p );
delete[] p;
//
// Sign the Message
//
// Set up for SignMessage()
byte* s = new byte[ signer.MaxSignatureLength() ];
if( !s ) { return false; }
// Sign...
AutoSeededRandomPool prng;
size_t length = signer.SignMessage( prng,
(const byte*) narrow.c_str(), narrow.length(), s );
// Convenience
string signature( (const char*)s, length );
// --- Begin Java Specific Conversion ---
//
// Convert: P1363 -> DER
//
// Crypto++ uses P1363 format.
// Java requires a DER encoded sequence.
{
// Determine size of required buffer
// We can call with a null buffer and 0 size
// when going in this direction
length = CryptoPP::DSAConvertSignatureFormat(
NULL, 0, DSA_DER, (const byte*)signature.c_str(),
signature.length(), DSA_P1363 );
// A buffer for the conversion
byte* buffer = new byte[ length ];
// Shit or Go Blind. You make the choice.
if( !buffer ) { return false; }
// Reuse length
length = CryptoPP::DSAConvertSignatureFormat(
buffer, length, DSA_DER, (const byte*)signature.c_str(),
signature.length(), DSA_P1363 );
// Reinitialize signature so that it can be used
// in the verifier below with minimal effort
signature = string( (const char*)buffer, length );
delete[] buffer;
}
// --- End Java Specific Conversion ---
//
// Save the Message and the Signature on Message
//
// mofs: message filestream
// sofs: signature filestream
ofstream mofs, sofs;
mofs.open("dsa.cpp.msg", ios_base::binary | ios_base::trunc );
sofs.open("dsa.cpp.sig", ios_base::binary | ios_base::trunc );
// Save Original Message
mofs.write( narrow.c_str(), (int)narrow.length() );
// Save Signature on Message
sofs.write( (const char*)signature.c_str(), (int)length );
// Cleanup
sofs.close();
mofs.close();
}
catch( CryptoPP::Exception& ex )
{
cerr << "Caught Error:" << endl;
cerr << " " << ex.what() << endl;
return false;
}
catch( std::exception& ex )
{
cerr << "Caught Error:" << endl;
cerr << " " << ex.what() << endl;
return false;
}
return true;
}
pictures_p1316 signature is not empty.docx
Description: MS-Word 2007 document
