Hello, Everyone,

It seems like when I sign a message using the RSASSA_PKCS1v15_SHA_Signer as in 
RSASignFile() in
test.cpp and then verify the message, verifying the prefix of the message returns 
"true" AND
the size of the prefix seems to vary randomly.

I generated a random byte string and signed it with RSASSA_PKCS1v15_SHA_Signer. Then I
repeatedly chopped off a byte from the end of the string and tried to verify it with
RSASSA_PKCS1v15_SHA_Verifier. I printed out the size of the biggest string for which 
the
verification does not succeed. 

Here is my output:

[EMAIL PROTECTED]> ./csaClient
Original message is of size: 2048
Signature verification failing for message prefix of size: 101
Signature verification failing for message prefix of size: 71
Signature verification failing for message prefix of size: 144
Signature verification failing for message prefix of size: 143
Signature verification failing for message prefix of size: 98
Signature verification failing for message prefix of size: 18
Signature verification failing for message prefix of size: 128
Signature verification failing for message prefix of size: 156
Signature verification failing for message prefix of size: 85
Signature verification failing for message prefix of size: 181
Signature verification failing for message prefix of size: 519
Signature verification failing for message prefix of size: 493
Signature verification failing for message prefix of size: 7
Signature verification failing for message prefix of size: 57
Signature verification failing for message prefix of size: 1203
Signature verification failing for message prefix of size: 71
Signature verification failing for message prefix of size: 135
Signature verification failing for message prefix of size: 232
Signature verification failing for message prefix of size: 82

Here is my code:

int main(int argc, char** argv) { 
  cout << "Original message is of size: " << RSA_CHALLENGE_SIZE*2 << endl;
  for(int i = 0; i < 20; i++ ) {
    testSigning();
  }
}

void testSigning() {
  AuthClient client;
  byte buffer[RSA_CHALLENGE_SIZE*2];
  client.getRandomPool().GenerateBlock(buffer, RSA_CHALLENGE_SIZE*2);
  ByteString* testString = new ByteString(buffer, RSA_CHALLENGE_SIZE*2);
  ByteString* signature = client.sign(testString);
  for(int i = 0; i < RSA_CHALLENGE_SIZE*2; i++) {
    ByteString* substring = testString -> substring(0, RSA_CHALLENGE_SIZE*2 - i);
    if( !client.verify(substring, signature) ) {
      cout << "Signature verification failing for message prefix of size: "<<
RSA_CHALLENGE_SIZE*2 - i << endl;
      break;
    }
  }
}


*******************************************************************************
*******************************************************************************
*******************************************************************************

/******************************************************************************/
/*                                                                            */
/*   Client-Server Authentication                                             */
/*   Olga Sayenko, [EMAIL PROTECTED]                                        */
/*   UIC Department of Computer Science                                       */
/*                                                                            */
/*   authClient.h                                                             */
/*                                                                            */
/*                                                                            */
/******************************************************************************/

#ifndef ABSTRACT_CLINET_H 
#define ABSTRACT_CLIENT_H 

#include "cryptoComponent.h"
#include "clientCommunication.h"

#define KEY_FILE_NAME ".client_csa_keys"

namespace ClientServerAuthentication {

  class AuthClient : public CryptoComponent, public ClientCommunication {
  public:
    AuthClient();
    AuthClient(ByteString* clientPublic, ByteString* clientPrivate, ByteString* 
serverPublic);
    ~AuthClient();
    void connect();
    void sendMessage(ByteString* message);
    ByteString* receiveMessage();
    void disconnect();
    ByteString* encrypt(ByteString* plaintext);
    ByteString* decrypt(ByteString* cyphertext);
    ByteString* sign(ByteString* message);
    bool verify(ByteString* message, ByteString* signature);
  private:
    ByteString* clientPublicKey;
    ByteString* clientPrivateKey;
    ByteString* serverPublicKey;
  };

}
#endif

*******************************************************************************
*******************************************************************************
*******************************************************************************

  ByteString* AuthClient::sign(ByteString* message) {
    return rsaSign(clientPrivateKey, message);
  }
  
  bool AuthClient::verify(ByteString* message, ByteString* signature) {
    return rsaVerify(clientPublicKey, signature, message);
  }


*******************************************************************************
*******************************************************************************
*******************************************************************************

#ifndef CRYPTO_COMPONENT_H
#define CRYPTO_COMPONENT_H

#include "osrng.h"
#include "pubkey.h"
#include "pssr.h"
#include "rsa.h"
#include "byteString.h"
using namespace CryptoPP;

namespace ClientServerAuthentication {

#define RSA_KEY_LENGTH                     1024
#define RSA_CHALLENGE_SIZE                 1024
#define RSA_ENCODED_PRIVATE_KEY_SIZE       1264
#define RSA_ENCODED_PUBLIC_KEY_SIZE         320
#define RSA_SIGNATURE_LENGTH                256
#define RSA_ENCRYPTED_BLOCK_SIZE            256
#define BLOCK_SIZE                           80

  class CryptoComponent {
  public:
     CryptoComponent();
     ByteString* generatePrivateKey();
     ByteString* generateRandomNumber(int size);
     ByteString* symmetricEncrypt(ByteString* key, ByteString* plaintext);
     ByteString* symmetricDecrypt(ByteString* key, ByteString* cyphertext);
     void generateRSAkey(ByteString** publicKey, ByteString** privateKey);
     ByteString* rsaEncrypt(ByteString* publicKey, ByteString* plaintext);
     ByteString* rsaDecrypt(ByteString* privateKey, ByteString* cyphertext);
     ByteString* rsaSign(ByteString* privateKey, ByteString* plaintext);
     bool rsaVerify(ByteString* publicKey, ByteString* signature, ByteString* message);
     ByteString* signAndEncrypt(ByteString* publicOther, ByteString* privateOwn, 
ByteString*
message);
     ByteString* CryptoComponent::decryptAndVerify(ByteString* publicOther, ByteString*
privateOwn, ByteString* cyphertext);
     RandomPool& getRandomPool();

  protected:
     AutoSeededRandomPool randomNumberPool;
  };

}
#endif


*******************************************************************************
*******************************************************************************
*******************************************************************************

 ByteString* CryptoComponent::rsaSign(ByteString* privateKey, ByteString* message) {
    if(message == NULL) {
      throw AuthException("Null message");
    }
    try {
      StringSource keySource(privateKey->toStdString(), true, new HexDecoder);
      RSASSA_PKCS1v15_SHA_Signer signer(keySource);
     
      std::string signature;
      StringSink* signatureSink = new StringSink(signature);
      HexEncoder* signatureEncoder = new HexEncoder(signatureSink);
      SignerFilter* signerFilter = new SignerFilter(randomNumberPool, signer,
signatureEncoder);
      StringSource(message->toStdString(), true, signerFilter);
      return new ByteString(signature.c_str());
    }
    catch( Exception e) {
      cout << "CryptoComponent::rsaSign: " <<  e.what() << endl;
      throw e;
    }
  }

  bool CryptoComponent::rsaVerify(ByteString* publicKey, ByteString* signature, 
ByteString*
message) {
    if(message == NULL) {
      throw AuthException("Null message");
    }
    StringSource publicKeySource(publicKey->toStdString(), true, new HexDecoder);
    RSASSA_PKCS1v15_SHA_Verifier verifier(publicKeySource);

    StringSource signatureSource(signature->toStdString(), true, new HexDecoder);
    if (signatureSource.MaxRetrievable() != verifier.SignatureLength()) {

      return false;
    }

    SecByteBlock signatureBlock(verifier.SignatureLength());
    signatureSource.Get(signatureBlock, signatureBlock.size());

    VerifierFilter* verifierFilter = new VerifierFilter(verifier);
    verifierFilter->Put(signatureBlock, verifier.SignatureLength());
    StringSource messageSource(message->toStdString(), true, verifierFilter);
    
    bool verified = verifierFilter->GetLastResult();
    return verified;
  }

=====
Olga Sayenko
http://www.cs.uic.edu/~osayenko
Department of Computer Science
University of Illinois at Chicago

Reply via email to