How to send and receive a DSA public/private signed message in Java



I cannot find any good (complete) documentation on how to exchange a public/private key signed message in Java.

I have yet to find a concise document on the minimum steps needed to generate a public key and private key using DSA, sign a byte[], and verify it.

The documentation from Oracle is too broken up and requires running across multiple JVMs.

Answer

I have successfully signed a byte array with a private key and verified it with a public key.

Example.

    byte[] data = "hello.".getBytes();

    /* Test generating and verifying a DSA signature */
    try {
        /* generate a key pair */
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
        keyGen.initialize(1024, new SecureRandom());
        KeyPair pair = keyGen.generateKeyPair();

        /* create a Signature object to use
         * for signing and verifying */
        Signature dsa = Signature.getInstance("SHA/DSA"); 

        /* initialize the Signature object for signing */
        PrivateKey priv = pair.getPrivate();
        dsa.initSign(priv);

        /* Update and sign the data */
        dsa.update(data);

        /* Now that all the data to be signed
         * has been read in, sign it */
        byte[] sig = dsa.sign();

        /* Verify the signature */

        /* Initialize the Signature object for verification */
        PublicKey pub = pair.getPublic();
        dsa.initVerify(pub);

        /* Update and verify the data */
        dsa.update(data);

        boolean verifies = dsa.verify(sig);
        Assert.assertTrue(verifies);
    } catch (Exception e) {
        System.err.println("Caught exception " + e.toString());
    }

In this version, I serialize the public key into a byte array and then create a PublicKey from that byte array.

    byte[] data = "hello.".getBytes();

    /* Test generating and verifying a DSA signature */
    try {
        /* generate a key pair */
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
        keyGen.initialize(1024, new SecureRandom());
        KeyPair pair = keyGen.generateKeyPair();

        /* create a Signature object to use
         * for signing and verifying */
        Signature dsa = Signature.getInstance("SHA/DSA"); 

        /* initialize the Signature object for signing */
        PrivateKey priv = pair.getPrivate();
        dsa.initSign(priv);

        /* Update and sign the data */
        dsa.update(data);

        /* Now that all the data to be signed
         * has been read in, sign it */
        byte[] sig = dsa.sign();

        /* Verify the signature */

        /* Initialize the Signature object for verification */
        PublicKey pub = pair.getPublic();
        /* Encode the public key into a byte array */
        byte[] encoded = pub.getEncoded();
        /* Get the public key from the encoded byte array */
        PublicKey fromEncoded = KeyFactory.getInstance("DSA", "SUN").generatePublic(new X509EncodedKeySpec(encoded));
        dsa.initVerify(fromEncoded);

        /* Update and verify the data */
        dsa.update(data);

        boolean verifies = dsa.verify(sig);
        Assert.assertTrue(verifies);
    } catch (Exception e) {
        System.err.println("Caught exception " + e.toString());
    }


Source: stackoverflow