Search for a signature algorithm that creates 32 or 16 byte keys in Java

It is not possible to match the size of the key generated using the public / private keys for the licensing application. Ive written a standalone example that creates a public / private key, creates a license by signing the user's public key email address, and then checks with the public key, license, and email address that the license was indeed encoded using the private key (obviously, it will not all be in the same class usually).

It all works, but the hexadecimal version of the license key is 96 characters (i.e. represents 48 bytes / 384 bits), which is slightly longer than I wanted (on the contrary, the length of the public / private keys is not a problem, but all the better). What can I use to generate 32 bytes (64 hexadecimal characters) or maybe 16 bytes (32 hexadecimal characters), and would it be more reasonable?

Choosing a different algorithm is somewhat difficult, since I do not understand the interaction between the algorithm selected for key generation

KeyPairGenerator.getInstance("DSA"); 

and algorithm for signing

 Signature.getInstance("SHA/DSA"); 

and I can not find the list for.

Another point when I create public / private key pairs, I specify the key size

 keyGen.initialize(1024, new SecureRandom()); 

neither of the public keys (443 bytes) or the private key (335 bytes) or the sum of both (778 bytes) matches 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 a conclusion, for example

 Creating license for: testuser@nowhere.com PrivateKeyHexLength:335 PublicKeyHexLength:443 CreateLicense:302c021425f7ad7289b073f82a1d808838f43e0134c5591402140d2a7a4e3967706d4659dc73ace6455040a5fc6b:Size:92 Resulttrue 
0
source share
1 answer

@Paul - I think your solution here will be to use ECDSA. Change your line of code

 final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); 

to

 final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA"); 

The keys are much shorter than the DSA - and I am sure that the signature of the hex version will be shorter. I suggest you use the main ECC curve, for example 256 or 128 bit.

Please let us know if this solves the problem.

0
source

All Articles