Cannot match up the size of key generated using public/private keys for licensing application. Ive written a self contained example that creates public/private key, create a license by signing user emailaddress with public key, and then check using public key, license and email address that the license indeed was encoded using private key (Obviously this wouldn't all be in one class usually).
This all works but the hex version of the license key is 96 characters (i.e representing 48 bytes/384 bits) which is a little longer than I wanted (In contrast the length of public/private keys is not a problem and the longer the better). What could I use to generate a 32 (64 hex chars) byte or maybe 16 byte (32 hex chars), and would the security of this be reasonable ?
Picking another algorithm is somewhat hard as I do not understand the the interaction between the algorithm picked for generating the keys
KeyPairGenerator.getInstance("DSA");
and the algorithm for signing
Signature.getInstance("SHA/DSA");
and I cant find a list for either.
One other point when I generate a public/private key pairs I specify key size of
keyGen.initialize(1024, new SecureRandom());
yet neither the public key (443 bytes) or the private key (335 bytes) or the sum of both (778 bytes) match this number.
import org.apache.commons.codec.binary.Hex;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
*
*/
public class CreateLicense
{
private String PUBLIC_KEY;
private String PRIVATE_KEY;
public static void main(final String[] args)
{
try
{
String email = args[0];
System.out.println("Creating license for:"+email);
CreateLicense cl = new CreateLicense();
cl.generatePublicPrivateKeyPair();
String license = cl.createLicense(email);
cl.checkLicense(email, license);
}
catch(Throwable t)
{
t.printStackTrace();
}
}
//Would only be done once on server
private void generatePublicPrivateKeyPair() throws Exception
{
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(1024, new SecureRandom());
final KeyPair pair = keyGen.generateKeyPair();
PrivateKey privateKey = pair.getPrivate();
PRIVATE_KEY=Hex.encodeHexString(privateKey.getEncoded());
PublicKey publicKey = pair.getPublic();
PUBLIC_KEY=Hex.encodeHexString(publicKey.getEncoded());
System.out.println("PrivateKeyHexLength:"+privateKey.getEncoded().length);
System.out.println("PublicKeyHexLength:"+publicKey.getEncoded().length);
}
private PrivateKey reinflatePrivateKey(String keyAsHexString) throws Exception
{
byte[] keyBytes = Hex.decodeHex(keyAsHexString.toCharArray());
final PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyBytes);
final KeyFactory keyFactory = KeyFactory.getInstance("DSA");
final PrivateKey privateKey = keyFactory.generatePrivate(privKeySpec);
return privateKey;
}
private PublicKey reinflatePublicKey(String keyAsHexString) throws Exception
{
byte[] keyBytes = Hex.decodeHex(keyAsHexString.toCharArray());
final X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(keyBytes);
final KeyFactory keyFactory = KeyFactory.getInstance("DSA");
final PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
return publicKey;
}
//License Create on server based on email address
private String createLicense(String emailAddress) throws Exception
{
String message=emailAddress;
PrivateKey privateKey = reinflatePrivateKey(PRIVATE_KEY);
final Signature dsa = Signature.getInstance("SHA/DSA");
dsa.initSign(privateKey);
dsa.update(message.getBytes());
final byte[] m1 = dsa.sign();
String license = Hex.encodeHexString(m1);
System.out.println("CreateLicense:"+license+":Size:"+license.length());
return license;
}
//Client checks that given known emailaddress and public key that a if a license was derived from
//that and corresponding privatekey it would match license.
private boolean checkLicense(String emailAddress, String license) throws Exception
{
String message=emailAddress;
PublicKey publicKey = reinflatePublicKey(PUBLIC_KEY);
final Signature dsa = Signature.getInstance("SHA/DSA");
dsa.initVerify(publicKey);
dsa.update(message.getBytes());
boolean result = dsa.verify(Hex.decodeHex(license.toCharArray()));
System.out.println("Result"+result);
return result;
}
}
gives output like
Creating license for:testuser@nowhere.com
PrivateKeyHexLength:335
PublicKeyHexLength:443
CreateLicense:302c021425f7ad7289b073f82a1d808838f43e0134c5591402140d2a7a4e3967706d4659dc73ace6455040a5fc6b:Size:92
Resulttrue