tags:

views:

136

answers:

6

Hi,

I have a method in java which generates a serial code based on a number of parameters.

Now I would like to have another method which accepts the same parameters + the serial code, and tells me whether or not this serial code is correct. However, I do not want to expose the serial code creation method, so if someone knows the method to check the correctness, he should not be able to construct a new code based on some other parameters.

Is this possible?

Some extra crucial information. I can't change the method which generates the serial code. Otherwise I could use some standerd public-private key algorithm. What I want is:

That's indeed what I need. Problem is that I cannot choose my own private key, this is a method I cannot change.

methodICannotChange("someinput") returns serialcode
methodICanInvent(serialcode, "someinput") returns true or false

and in witch it is 'impossible' to generate a new serialcode when nowing the implementation of methodICanInvent.

A: 

Why not have a SerialCode object ? Pass the parameters into the constructor. If the parameters are valid, then your SerialCode object instantiates. If not, then the constructor fails.

This way, all your SerialCode objects represent valid serial codes. Your client can assert the validity simply by possessing an instantiated SerialCode object.

You may want to provide a SerialCodeFactory to create these objects (see here for info on factories/factory methods), and not expose this to your client, but merely the SerialCode objects (via package scoping or other means).

Brian Agnew
I'm affraid this does not solve my problem. I would like to prevent someone being able to easily create his own serial code by decompiling my class files.
Fortega
+2  A: 

The security of your serial code must not depend on the knowledge of the algorithm (i.e. to have a unknown algorithm) and the "public" input parameters.

It should only depend on a secret kept under lock and key:

serialNumber(input parameters, secret) -> serial number

User of the algorithm that do not know the secret have not to be able to guess the secret or produce a useful serial number in an economical interesting time span without the secret.

Secure hash functions are designed to fulfill your requirements.

serialNumber(parameters, secret) = md5(parameters & secret)
verify(parameters, secret, serialNumber) = md5(parameters & secret) == serialNumber

Depending on your security requirements you need one global secret or multiple secret for multiple contexts.

This solution works only if creation and verification of serial numbers is performed in the same place. (Otherwise public key cryptography has to be used.)

Thomas Jung
Hi, the verify method should not be able to create the serial number, as it can easily be read by the customers (using decomposition of the class files)
Fortega
I had a client-server-scheme in mind. Seriale numbers are created and verfied in the same place. If you have to be able to verify serial numbers in untrusted places you have to use a public key cryptography.
Thomas Jung
+3  A: 

What you are doing is basically creating custom hash function. Hash function allows only to answer if given digest matches given input data. I.e. anyone is able to create the digest for the data.

What you really want is a digital signature. I.e. the general idea is to do the following:

  1. Create private and public keys;
  2. Expose public key to any client;
  3. Create digest for the data and sign it with the private key any data should be delivered to the client;
  4. Client decrypts encrypted message digest with your public key, calculates message digest for the given data and checks that calculated digest is the same as delivered;

I.e. client may be sure that the digest received from the server is correct if he or she is able to decrypt it using your public key.

denis.zhdanov
Problem is I cannot modify the method which generates the serial code based on the input. (I added some extra information to the question: see above)
Fortega
A: 

I'm afraid, the hardest you try, there's always somebody who can hack your code and either create a key generator or apply a patch to disable the checking of the serial number.

You can only make life difficult for them:

  1. For the generation of your serial number, use an asymmetric algorithm where you generate the number with a private key and validate it (at the client) with a public key. I've seen solutions, where the license file is digitally signed at the vendor and the application just checks, if the file is present and is correctly signes.
  2. Obfuscate your code. This will not prevent from decompiling but maybe a lot hackers don't think it's worth the effort to analyse obfuscated code.
Andreas_D
+2  A: 

You could use digital signature to make it bullet proof. The code for creating the serial code does not have to be rolled out to your customers.

alt text

In your case the data part would be the parameters mentionend (I guess a user name). You could convert these to a string representation (a string can easily be hashed). The signature is the serial code which you give to your customers.

In the client code the digital signature / serial key can be validate using only the given parameters and the serial key itself. Of course you have to create a public and prvate key. The public key has to be included in the code which is rolled out to the customers. The private key has to be kept safe.

There are classes which help creating digital signatures. Look here for a tutorial.

spa
Same comment as above: the serial code method is already defined, I cannot change it. This code returns the serial code which is distributed to the users. Imagine the users already having a serial code.
Fortega
A: 

Given that you cannot change the serial code generation to using asymetric cryptography, I would move the validation to a web service. So methodICanInvent(serialcode, "someinput") invokes a web service performing the validation and returns true or false.

The reason for this is that a user can easily decompile your validation code which can be used to gather information for a key generator.

spa