Tutorial of ECDSA algorithm to sign a string

前端 未结 2 1697
你的背包
你的背包 2021-02-01 21:54

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

相关标签:
2条回答
  • 2021-02-01 22:41
    class ECCCipher {
        @Override
        public byte[] sign(PrivateKey privateKey, String message) throws Exception {
            Signature signature = Signature.getInstance("SHA1withECDSA");
            signature.initSign(privateKey);
    
            signature.update(message.getBytes());
    
            return signature.sign();
        }
    
        @Override
        public boolean verify(PublicKey publicKey, byte[] signed, String message) throws Exception {
            Signature signature = Signature.getInstance("SHA1withECDSA");
            signature.initVerify(publicKey);
    
            signature.update(message.getBytes());
    
            return signature.verify(signed);
        }
    }
    

    ========================

    public class ECCCipherTest {
    
    private final KeyPairGenerator keygen;
    
    public ECCCipherTest() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        Security.addProvider(new BouncyCastleProvider());
        this.keygen = KeyPairGenerator.getInstance("ECDSA", "BC");
        keygen.initialize(new ECGenParameterSpec("brainpoolP384r1"));
    }
    
    @Test
    public void ECC_CipherTest_1() throws Exception {
        String message = "hello world";
    
        ICipher<PrivateKey, PublicKey> cipher = new ECCCipher();
        KeyPair keyPair = keygen.generateKeyPair();
    
        byte[] encrypted = cipher.sign(keyPair.getPrivate(), message);
    
        Assert.assertTrue(cipher.verify(keyPair.getPublic(), encrypted, message));
    }
    

    }

    this is a small code snippet from my project. it works for me. I have included one junit test as well; hopefully this helps.

    just in case anyone wonders how we load the private key and pubkey: (note: privKey is the byte array representing the BigInteger in java, and the pubKey is the curve point in binary format)

        @Override
    public PrivateKey generatePrivateKey(byte[] keyBin) throws InvalidKeySpecException, NoSuchAlgorithmException {
        ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
        KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
        ECNamedCurveSpec params = new ECNamedCurveSpec("secp256k1", spec.getCurve(), spec.getG(), spec.getN());
        ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(new BigInteger(keyBin), params);
        return kf.generatePrivate(privKeySpec);
    }
    
    @Override
    public PublicKey generatePublicKey(byte[] keyBin) throws InvalidKeySpecException, NoSuchAlgorithmException {
        ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
        KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
        ECNamedCurveSpec params = new ECNamedCurveSpec("secp256k1", spec.getCurve(), spec.getG(), spec.getN());
        ECPoint point =  ECPointUtil.decodePoint(params.getCurve(), keyBin);
        ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
        return kf.generatePublic(pubKeySpec);
    }
    
    0 讨论(0)
  • 2021-02-01 22:43

    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 javax.xml.bind.DatatypeConverter;
    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));
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题