Game Development Community

Signature Verification Issue, PHP or C++?

by Robert Fritzen · in Technical Issues · 02/05/2011 (9:08 am) · 6 replies

So I have a little test program on my web server that is using phpseclib to generate RSA keypairs for what eventually will be the "CA" key. the only problem is the output on PHP is saying that verification is correct, while C++ is saying otherwise due to the following error: "PK_Signer: key too short for this signature scheme". How can I go about fixing this to complete my authentication system?

PHP w/ output:
<?php

echo "BEGIN SIGN <p>";
include("../php/Crypt/RSA.php");

$rsa = new Crypt_RSA();
extract($rsa->createKey(512));

$plaintext = 'terrafrost';

echo "PRIV: ". $privatekey ." <p>";
echo "PUB: ". $publickey ." <p>";

$rsa->loadKey($privatekey);
$signature = $rsa->sign($plaintext);

echo "S: ".$signature."<p>";
echo "H: ".bin2hex($signature)."<p>";

$rsa->loadKey($publickey);
echo $rsa->verify($plaintext, $signature) ? 'verified<p>' : 'unverified<p>';


echo "DONE";


?>

output:
BEGIN SIGN

PRIV: -----BEGIN RSA PRIVATE KEY----- MIIBOgIBAAJBAIIB5l2bsi3mTe1ym+1jCXbWWbbphx3bKEvWSnK8FsCoV7FaCEDQtutjdStn5sAv FzPHA3OBfOucPhHQfE/1JEkCAwEAAQJAF8DNHDFEPsqjVkzoXFkJ86J6RccpHrVaCXEfrRLcfVp/ 1dMHKAPcNgDfhjIhbxayVlUtayW3dUjEcTQadNbZeQIhAI35QHmXrBhmaTk4aN58WiDthpWXjkDe cCcsisjL/smvAiEA6mxP1zNym3yH3PU6IjGdFn4w9KEssK1t5uCkgYJ7B4cCIDKNCFcDGUTK2jaE jlqBvnmw+VW0U/NnAFoCcxwR/pODAiEAlYCmGpTRDqCI9T3f6VbC3El2Z00y9ypj4M57m6zfUZkC IG+mPY+ffC+n86Y6NheX/b4s8u2AypS8DkHy474D+HbO -----END RSA PRIVATE KEY-----

PUB: -----BEGIN PUBLIC KEY----- MEgCQQCCAeZdm7It5k3tcpvtYwl21lm26Ycd2yhL1kpyvBbAqFexWghA0LbrY3UrZ+bALxczxwNz gXzrnD4R0HxP9SRJAgMBAAE= -----END PUBLIC KEY-----

S: 1&iuml;&iquest;&frac12;&Acirc;&iexcl;|&acirc;€&sup1;b&Acirc;&micro;&Atilde;“{BQ&Atilde;&cedil;&Acirc;&sup1;&Acirc;&para;&Acirc;&cedil;&Atilde;ž&Atilde;Š&Acirc;&yen;*cC&Acirc;&uml;&Atilde;&plusmn;&Acirc;&cent;KS&Acirc;&sup2;&Acirc;&Acirc;&uml;&acirc;€&deg;&acirc;€˜m&Acirc;&shy;&Atilde;&reg;t&Acirc;&sect;f|P&Atilde;&cedil;&Atilde;&acirc;€&iexcl;&Atilde;&brvbar;b&acirc;€š&Atilde;–W'&acirc;€&deg;&Euml;œ&Acirc;&ordm;&Acirc;&frac34;"~! &acirc;€ž?

H: 3100a17c1f8b62b5d37b420451f8b9b6b8decaa52a6343a808f1a24b53b29da889916dadee74a7667c50f8d087e66282d6572789981cbabe227e21090a84043f

verified

DONE

C++
bool xxz568::caVerify(std::string message, std::string signature) {

   const char * CA_PUBLIC_KEY = {"MEgCQQCCAeZdm7It5k3tcpvtYwl21lm26Ycd2yhL1kpyvBbAqFexWghA0LbrY3UrZ+bALxczxwNz gXzrnD4R0HxP9SRJAgMBAAE="};

   std::string dec, fin;
   Base64Decode(CA_PUBLIC_KEY, dec);
   HexEncode(dec, fin);
   cout << "CA P: " << fin << endl;

   Integer rsaPub(fin.c_str());
    
   InvertibleRSAFunction certAuth;
   certAuth.SetModulus(rsaPub);

   cout << "CA MOD: " << certAuth.GetModulus() << endl;

   RSA::PublicKey publicKey(certAuth);
   std::string holder;

   try {
      RSASSA_PKCS1v15_SHA_Verifier verifier(publicKey);

      HexDecode(signature, holder);

      StringSource(message+holder, true,
          new SignatureVerificationFilter(
              verifier, NULL,
              SignatureVerificationFilter::THROW_EXCEPTION
         ) // SignatureVerificationFilter
      ); // StringSource
   }
   catch(CryptoPP::Exception e) {
	  cout << e.GetWhat() << endl;
	  cout << e.GetErrorType() << endl;
      return false;
   }

   return true;
}

Hopefully we can get this figured out soon, you guys have been great on helping me with this system so far.

#1
02/05/2011 (9:24 am)
If you are still having issues, you may want to try asking your question at Stack Overflow or the CryptoPP mailinglist. The CryptoPP mailinglist would probably be a good place to ask a question like that.
#2
02/07/2011 (3:20 pm)
Asked there, but it seems like a pretty quiet group, if you know what I mean. I'm just going to try something else (different method to accomplish the same thing). I'll report back when I've finished coding.
#3
02/08/2011 (8:16 am)
Alright, it appears the mailing list isn't going to help me.

But, here is where I stand. I decided not to go with the "different" method, I would have needed to re-write a bunch of other things, and at this point, it's not really logical for me to do so.

I've modified my caVerify code a bit, and it runs now without any exceptions, but it does not accept my signature.

Here is the new caVerify code + signature and original data.

*EDIT* added public exponent part, same thing

bool xxz568::caVerify(std::string message, std::string signature) {

   const char * CA_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/YP/EBPTQUjsav6Uinz1GZgudRFm6yCzTNM4C6IxMPfOLU4yRzTRKXhJREsc+IcFr09J121Qbe6RttZT8DgEDFf8xRjjWQWndEDkoA5mfF7W3rMhY8erGai2StbS1gONLAnd8xHuHioHoWIrsHwhm8oDw1TQ8rwd7xu/wteOfowIDAQAB";

   std::string dec, fin;
   Base64Decode(CA_PUBLIC_KEY, dec);
   HexEncode(dec, fin);
   Integer rsaPub(fin.c_str()), rsaExp("65537");
    
   InvertibleRSAFunction certAuth;
   certAuth.SetModulus(rsaPub);
   certAuth.SetPublicExponent(rsaExp);
   RSA::PublicKey publicKey(certAuth);
   std::string holder;

   try {
      RSASSA_PKCS1v15_SHA_Verifier verifier(publicKey);
	  verifier.AccessKey().Initialize(rsaPub, rsaExp);

	  size_t length = verifier.MaxSignatureLength();
      SecByteBlock binsignature(length);

      HexDecode(signature, holder);
	  memcpy(binsignature, holder.c_str(), length);

	  bool result = verifier.VerifyMessage((const byte*)message.c_str(), message.length(), binsignature, binsignature.size());
      return result;  
   }
   catch(CryptoPP::Exception e) {
	  cout << e.GetWhat() << endl;
	  cout << e.GetErrorType() << endl;
      return false;
   }
}

//MAIN CODE (snippet):
   std::string signedMessage = "terrafrost";
   std::string caSigned = "bb9b1082ac2e725d68cd47b2daf4e20a963e62639527b0059ac4553fa8ed5a342948b310540bac8ff0546393c22d2271911c3d343874cbda2ad1ca157c999985283cd4d0e649b5b76b70924bef7aba2be6d6a5bbcf65abf1d1dc9d7e27156ca3e20e6dc9c8f07919a8b6c1c2c3dd440d5eef6e24e3f975245ca77334e527bdd6";
   bool ca = auth.caVerify(signedMessage, caSigned);
   bool ca2 = auth.caVerify(signedMessage, caSigned+"bad");

   cout << "CA: " << ca << "| CA BAD: " << ca2 << endl;

*EDIT #2*
Trying the filters, I get a different error:
VerifierFilter: Digital Signature Not Valid

bool xxz568::caVerify(std::string message, std::string signature) {

   const char * CA_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/YP/EBPTQUjsav6Uinz1GZgudRFm6yCzTNM4C6IxMPfOLU4yRzTRKXhJREsc+IcFr09J121Qbe6RttZT8DgEDFf8xRjjWQWndEDkoA5mfF7W3rMhY8erGai2StbS1gONLAnd8xHuHioHoWIrsHwhm8oDw1TQ8rwd7xu/wteOfowIDAQAB";

   std::string dec, fin;
   Base64Decode(CA_PUBLIC_KEY, dec);
   HexEncode(dec, fin);
   Integer rsaPub(fin.c_str()), rsaExp("65537");
    
   InvertibleRSAFunction certAuth;
   certAuth.SetModulus(rsaPub);
   certAuth.SetPublicExponent(rsaExp);
   RSA::PublicKey publicKey(certAuth);
   std::string holder;

   try {
      RSASSA_PKCS1v15_SHA_Verifier verifier(publicKey);
	  verifier.AccessKey().Initialize(rsaPub, rsaExp);

      HexDecode(signature, holder);

      StringSource(message+holder, true,
          new SignatureVerificationFilter(
              verifier, NULL,
              SignatureVerificationFilter::THROW_EXCEPTION
         ) // SignatureVerificationFilter
      ); // StringSource
   }
   catch(CryptoPP::Exception e) {
	  cout << e.GetWhat() << endl;
	  cout << e.GetErrorType() << endl;
      return false;
   }
}

*END EDIT #2*

both ca/ca bad say the data is incorrect. This is probably as close as I've gotten to getting this thing to work. I'll keep trying some things out, but if you see anything that can get this working, please let me know.
#4
02/08/2011 (3:20 pm)
For PHP, try this:

$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);

By default it uses PSS signatures (which, in theory, provide better security) instead of PKCS1 signatures.

You might also have more success if you ask on the phpseclib support forums.
#5
02/08/2011 (3:34 pm)
Added that line, same Not Valid Digital Signature error.

and while they have more knowledge on the PHP issues, they are very lacking when it comes to the C++ sided problems.

I have asked there though for PHP questions on this system already. :)

I'll keep trying, maybe I'm still screwing something up in my PHP or C++, who knows, maybe both.
#6
02/11/2011 (7:08 pm)
Great news, solved this issue.

It's going to take me a bit to get all of my scripts together, but once I do so, I should be able to get a nice resource up on using this system, thanks for the help!

I'm going to have to code a online CA creator for everyone to use their own CA Key (because I'm obviously not going to just give you the one I'm using :)). After that, the current resource mixes both TS and C++ code, I plan on eventually migrating it all to C++, but I do not have enough experience with the engine to be in the know how for that at this time. Other than that, I can hopefully have a nice RSA resource in your hands soon enough.