javapublic-key-encryptionencryption-asymmetricdsa

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.


Solution

  • 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());
        }