0

I'm developing a key generator that generates RSA signatures that are to be downloaded to the clients computer.

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.

[edit updated the code with the suggestion, but still no success.]

The Python 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()

And the C++ Code:

#include <string.h>
#include <assert.h>
#include <iostream>
#include <fstream>
#include <string>
#include <memory>
#include <vector>

#include <botan/botan.h>
#include <botan/look_pk.h>
#include <botan/rsa.h>

#include <QtCore>
#include "lib/debug.hpp"
#include <QDebug>

#define Q(AAA) qDebug() << #AAA <<" " << AAA << endl;
#define P(X) std::cout << #X <<" = " << X << " "<< std::endl;

using namespace Botan;

static BigInt to_bigint(const std::string& 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 < l.size(); i++) {
        if (verifier)
            delete verifier;
        verifier = get_pk_verifier(pub_key, l[i].toStdString() );

        bool is_valid = verifier->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->verify_message(
                      mac_and_plugin_hex.data(),mac_and_plugin_hex.length(),
                      qByteArray_sig.data(), qByteArray_sig.length()
                  );
        P(is_valid);

        is_valid = verifier->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);;
}
  • Welcome to Stack Overflow. Please reduce your code to the relevant parts. Right now people will have a difficult time to find what makes you trouble. Please also read http://stackoverflow.com/questions/how-to-ask –  Feb 03 '12 at 12:14

1 Answers1

1

In the piece of Python code, you are creating an RSA signature that does not follow any real protocol or standard. In other words, it's raw and in most cases it is not secure.

Instead, you should use something like PSS (use the pycrypto module PKCS1_PSS here). In the Botan code, that can by verified with the EMSA4 encoding.

Alternatively you could use PKCS#1 v1.5. In Botan, that is EMSA3.

In either case, the hash algorithm must be the same at both sides.

  • Thanks for the reply ! Will post more info with results ! – user1185744 Feb 06 '12 at 14:27
  • Difficult to help more without seeing the actual code that fails. To say, in the code you posted you randomly generate the signing key each time, whereas the verification key is hardcoded. That clearly will not work, but I guess you don't do that in reality. In these cases, you may try to sign/verify also with openssl (as a third proven implementation). – SquareRootOfTwentyThree Feb 19 '12 at 14:16
  • I've been busy, so i couldn't test this again. Will try again when i get some free time. – user1185744 Feb 28 '12 at 19:38