Search code examples
javacryptographydigital-signaturebouncycastle

Tutorial of ECDSA algorithm to sign a string


Can you help me to find a simple tutorial of how sign a string using ECDSA algorithm in java. But without using any third-party libraries like bouncycastle. Just JDK 7. I found it difficult to search a simple example, I'm new to cryptography.


import java.io.*;
import java.security.*;

public class GenSig {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        /*
         * Generate a DSA signature
         */

        try {

            /*
             * Generate a key pair
             */

            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");

            keyGen.initialize(1024, random);

            KeyPair pair = keyGen.generateKeyPair();
            PrivateKey priv = pair.getPrivate();
            PublicKey pub = pair.getPublic();

            /*
             * Create a Signature object and initialize it with the private key
             */

            Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");

            dsa.initSign(priv);

            String str = "This is string to sign";
            byte[] strByte = str.getBytes();
            dsa.update(strByte);

            /*
             * Now that all the data to be signed has been read in, generate a
             * signature for it
             */

            byte[] realSig = dsa.sign();
            System.out.println("Signature: " + new String(realSig));


        } catch (Exception e) {
            System.err.println("Caught exception " + e.toString());
        }
    }
}

How to modify it for ECDSA?


Solution

  • Here is small example based on your example.

    NOTE: this is the original code for this answer, please see the next code snippet for an updated version.

    import java.math.BigInteger;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.SecureRandom;
    import java.security.Signature;
    
    public class ECDSAExample {
    
        public static void main(String[] args) throws Exception {
            /*
             * Generate an ECDSA signature
             */
    
            /*
             * Generate a key pair
             */
    
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    
            keyGen.initialize(256, random);
    
            KeyPair pair = keyGen.generateKeyPair();
            PrivateKey priv = pair.getPrivate();
            PublicKey pub = pair.getPublic();
    
            /*
             * Create a Signature object and initialize it with the private key
             */
    
            Signature dsa = Signature.getInstance("SHA1withECDSA");
    
            dsa.initSign(priv);
    
            String str = "This is string to sign";
            byte[] strByte = str.getBytes("UTF-8");
            dsa.update(strByte);
    
            /*
             * Now that all the data to be signed has been read in, generate a
             * signature for it
             */
    
            byte[] realSig = dsa.sign();
            System.out.println("Signature: " + new BigInteger(1, realSig).toString(16));
    
        }
    }
    

    UPDATE: Here is slightly improved example removing deprecated algorithms. It also explicitly requests the NIST P-256 curve using the SECG notation "secp256r1" as specified in RFC 8422.

    import java.math.BigInteger;
    import java.security.*;
    import java.security.spec.ECGenParameterSpec;
    
    public class ECDSAExample {
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws Exception {
            /*
             * Generate an ECDSA signature
             */
    
            /*
             * Generate a key pair
             */
    
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
    
            keyGen.initialize(new ECGenParameterSpec("secp256r1"), new SecureRandom());
    
            KeyPair pair = keyGen.generateKeyPair();
            PrivateKey priv = pair.getPrivate();
            PublicKey pub = pair.getPublic();
    
            /*
             * Create a Signature object and initialize it with the private key
             */
    
            Signature ecdsa = Signature.getInstance("SHA256withECDSA");
    
            ecdsa.initSign(priv);
    
            String str = "This is string to sign";
            byte[] strByte = str.getBytes("UTF-8");
            ecdsa.update(strByte);
    
            /*
             * Now that all the data to be signed has been read in, generate a
             * signature for it
             */
    
            byte[] realSig = ecdsa.sign();
            System.out.println("Signature: " + new BigInteger(1, realSig).toString(16));
    
        }
    }