import java.math.BigInteger; import java.security.SecureRandom; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.security.PrivateKey; import java.security.Signature; import java.security.KeyPair; import java.security.interfaces.DSAPrivateKey; class DSASigGen { public static void print_hex(byte buffer[]) { for(int i = 0; i != buffer.length; ++i) { // There must be an easier way to do this (right?) int intval = buffer[i]; if(intval < 0) intval += 256; String s = Integer.toHexString(intval); if(s.length() == 1) s = "0" + s; System.out.print(s); } System.out.println(""); } /* Generate a DSA key and print 2 lines to stdout in hex ASN.1 DSA public key DSA signature of empty string with that key (exact string doesn't matter) */ public static void main(String[] args) { try { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); /* JCE docs have prng setting a 'user seed', though of course without any guidance about how to actually create one. Doesn't seem to make any difference, but doing it here anyway. The guessing code does not make any reliance on what is set here since it only affects the key gen, feel free to modify this. */ SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); byte[] user_seed = prng.generateSeed(20); prng.setSeed(user_seed); keyGen.initialize(1024, prng); KeyPair pair = keyGen.generateKeyPair(); Signature dsa = Signature.getInstance("SHA1withDSA"); PrivateKey priv = pair.getPrivate(); dsa.initSign(priv); BigInteger x = ((DSAPrivateKey)priv).getX(); System.err.println("Private key is " + x); /* The Java standard lib does not seem to include either a) Support for writing PEM format keys b) A base64 encoder/decoder ?!? WTF Sun, seriously. Just write the raw ASN.1 as hex and decode it on the other side for minimal hassles. Could use org.apache.commons.codec.binary.Base64 or whatever and form PEM headers by hand, but doesn't seem worth the bother. */ PublicKey pubKey = pair.getPublic(); byte[] encKey = pubKey.getEncoded(); print_hex(encKey); byte[] data = new byte[0]; dsa.update(data); byte[] sig = dsa.sign(); print_hex(sig); } catch(Exception e) { System.out.println(e); } } }