title: How to make Botan RSA signature verification match that of PyCrypto
body: <p>I'm developing a key generator that generates RSA signatures that
  are to be downloaded to the clients computer.</p>
  
  <p>In the clients computer i would like to use a RSA signature and a
  public key to validate the string.
  What i would like to know, if you can help, is what is the algorithm
  that i should use to get the signature validated or what is wrong with
  my code.</p>
  
  <p>[edit updated the code with the suggestion, but still no success.]</p>
  
  <p>The Python code:</p>
  
  <pre><code>from Crypto.Signature import PKCS1_PSS
  from Crypto.Hash import SHA
  from Crypto.PublicKey import RSA
  from Crypto import Random
  
  key_priv = RSA.generate(1024)#, random_generator)
  #key_priv = RSA.importKey(open('key.priv.pem.rsa').read())
  
  key_pub  = key_priv.publickey()
  n, e = key_pub.n, key_pub.e
  
  p,q,d,u = key_priv.p, key_priv.q, key_priv.d, key_priv.u
  
  print "char n[] = \"",n,"\";"
  print "char e[] = \"",e,"\";"
  
  #print "key_pub.exportKey(): ",key_pub.exportKey()
  
  mac = '192.168.0.106'
  plugin = 'Bluetooth'
  text = plugin + mac
  
  hash = SHA.new()
  hash.update(text)
  
  #signature = key_priv.sign(hash, None, 'PKCS1')[0]
  #print "signature: ", signature
  
  #random_generator = Random.new().read
  #signature = key_priv.sign(hash, '')
  
  signer    = PKCS1_PSS.new(key_priv)
  
  # signature = signer.sign(hash)
  signature = open('plugin_example.signature').read()
  
  print "type(signature)", type(signature) #str
  print "signature: ", signature
  
  verifier = PKCS1_PSS.new(key_pub)
  if verifier.verify(hash, signature):
      print "The signature is authentic."
  else:
      print "The signature is not authentic."
  
  fd = open("plugin_example.signature", "w")
  fd.write(signature)
  fd.close()
  
  fd = open("key.pub.pem.rsa", "w")
  fd.write(key_pub.exportKey())
  fd.close()
  
  fd = open("key.priv.pem.rsa", "w")
  fd.write(key_priv.exportKey())
  fd.close()
  </code></pre>
  
  <p>And the C++ Code:</p>
  
  <pre><code>#include &lt;string.h&gt;
  #include &lt;assert.h&gt;
  #include &lt;iostream&gt;
  #include &lt;fstream&gt;
  #include &lt;string&gt;
  #include &lt;memory&gt;
  #include &lt;vector&gt;
  
  #include &lt;botan/botan.h&gt;
  #include &lt;botan/look_pk.h&gt;
  #include &lt;botan/rsa.h&gt;
  
  #include &lt;QtCore&gt;
  #include "lib/debug.hpp"
  #include &lt;QDebug&gt;
  
  #define Q(AAA) qDebug() &lt;&lt; #AAA &lt;&lt;" " &lt;&lt; AAA &lt;&lt; endl;
  #define P(X) std::cout &lt;&lt; #X &lt;&lt;" = " &lt;&lt; X &lt;&lt; " "&lt;&lt; std::endl;
  
  using namespace Botan;
  
  static BigInt to_bigint(const std::string&amp; h)
  {
      return BigInt::decode((const byte*)h.data(),
                            h.length(), BigInt::Hexadecimal);
  }
  
  
  int main(int argc, char ** argv) {
  
      Botan::LibraryInitializer init;
  
      QByteArray mac = "192.168.0.106";
      QByteArray plugin = "Bluetooth";
      QByteArray mac_and_plugin = plugin+mac;
  
      QByteArray mac_and_plugin_hex = QCryptographicHash::hash ( mac_and_plugin, QCryptographicHash::Sha1 ).toHex();
  
      QByteArray qByteArray_sig;
      QFile file ( argv[1] );
      file.open ( QIODevice::ReadOnly );
      if ( file.isReadable() )
      {
          qByteArray_sig = file.readAll();
      }
      file.close();
  
      QByteArray qByteArray_sig_hex = qByteArray_sig.toHex();
  
      char n[] = "137758869720100695031597743484335597584728606037599895664824678915370363634933922524373276431650126408515526550739072301333537631796375930381713667037665579467940926539847824669399430790335904629465572107797677521774814742987023253982675971904413266030976887012380999213491205226382726115118193377641942499979";
      char e[] = "65537";
  
      BigInt big_n = to_bigint(n);// mod
      BigInt big_e = to_bigint(e);// exp
      RSA_PublicKey pub_key(big_n,big_e);
  
      PK_Verifier* verifier = 0;
  
      QStringList l;
      l.push_back("EMSA1(SHA-1)");
      l.push_back("EMSA3(SHA-1)");
      l.push_back("EMSA4(SHA-1)");
      l.push_back("EMSA1(SHA-256)");
      l.push_back("EMSA3(SHA-256)");
      l.push_back("EMSA4(SHA-256)");
      l.push_back("EMSA3(MD5)");
  
      P(qByteArray_sig.length());
  
      for (int i = 0 ; i &lt; l.size(); i++) {
          if (verifier)
              delete verifier;
          verifier = get_pk_verifier(pub_key, l[i].toStdString() );
  
          bool is_valid = verifier-&gt;verify_message(
                              mac_and_plugin_hex.data(),mac_and_plugin_hex.length(),
                              qByteArray_sig_hex.data(), qByteArray_sig_hex.length()
                          );
          P(is_valid);
  
          is_valid = verifier-&gt;verify_message(
                        mac_and_plugin_hex.data(),mac_and_plugin_hex.length(),
                        qByteArray_sig.data(), qByteArray_sig.length()
                    );
          P(is_valid);
  
          is_valid = verifier-&gt;verify_message(
                        mac_and_plugin.data(),mac_and_plugin.length(),
                        qByteArray_sig.data(), qByteArray_sig.length()
                    );
          P(is_valid);
  
      }
  
      Q(qByteArray_sig);
      Q(qByteArray_sig_hex);;
  }
  </code></pre>