4

I need to use ECDSA algorithm to sign a message and send to receiver in java. Then, receiver should verify sender's signature.

So, for this, receiver has sender's public key but in byte array format after converting java.security.PublicKey to byte array by the command bellow:

byte[] byteArrayPublicKey = publickey.getEncoded();

The format of public key in ECDSA algorithm (before converting it to byte array) is as follow:

Public Key:

X: 8a83c389e7bb817c17bf2db4ed71055f18342b630221b2a3a1ca752502dc2e21

Y: 3eaf48c9ab1700fe0966a0cde196b85af66bb8f0bacef711c9dca2368f9d8470

But, the problem is to convert this byte array to usable format to verify the signature that is java.security.PublicKey by receiver.

In general, is there any solution to verify the signature without converting it to byte array? In the other word, the problem is to verify the signature by sender's public key, using any method.

Questioner
  • 662
  • 1
  • 10
  • 26
  • If you have the result of `PublicKey.getEncoded()` that is **not** just the public point X and Y; it contains an AlgId including parameters as well. Java calls that "X509" encoding, and you can feed it directly to `KeyFactory.getInstance("EC").generatePublic()`. If you actually have only separate point coordinates **and the curve**, see http://stackoverflow.com/questions/22646792/how-does-one-convert-a-public-ec-code-point-and-curve-name-into-a-publickey and http://stackoverflow.com/questions/30445997/loading-raw-64-byte-long-ecdsa-public-key-in-java . – dave_thompson_085 Jun 20 '15 at 00:35

1 Answers1

3

But, the problem is to convert this byte array to usable format to verify the signature that is java.security.PublicKey by receiver.

You can solve the problem like this way:

public static ECPublicKey genEcPubKey() throws Exception {
    KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");
    java.security.PublicKey ecPublicKey = (ECPublicKey) factory
            .generatePublic(new X509EncodedKeySpec(Helper
                    .toByte(ecRemotePubKey))); // Helper.toByte(ecRemotePubKey)) is java.security.PublicKey#getEncoded()
    return (ECPublicKey) ecPublicKey;
}

Note that, you need BouncyCastle provider to do that.

But question remains, how you generate the private key?

public KeyPair ecKeyPairGenerator(String curveName) throws Exception {
    KeyPair keyPair;
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
            "ECDSA", "BC");
    ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(
            curveName);
    keyPairGenerator.initialize(ecGenParameterSpec, new SecureRandom());
    keyPair = keyPairGenerator.generateKeyPair();
    java.security.PublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
    System.out.println("JAVA EC PublicKey: "
            + Helper.toHex(ecPublicKey.getEncoded()));

    // write private key into a file. Just for testing purpose
    FileOutputStream fileOutputStream = new FileOutputStream(
            "ECPrivateKey.key");
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(
            fileOutputStream);
    objectOutputStream.writeObject(keyPair.getPrivate());
    objectOutputStream.close();
    return keyPair;
}

I have the full running code for EC sign/verify in github. You can take a look for better understanding.

mazhar islam
  • 5,561
  • 3
  • 20
  • 41
  • Rakeb void, thank you so much for your useful and great answer. just another thing should be added that I explained it in another question here: http://stackoverflow.com/questions/30956867/signature-verification-is-always-false-java?noredirect=1#comment49946507_30956867 the matter is respecting ASN.1 in signature and verification. – Questioner Jun 20 '15 at 17:51
  • If this is the answer you are looking for then try to accept it. Ty. – mazhar islam Jun 20 '15 at 18:31
  • I try to vote for it to accept this answer, but in fact, minimum 15 reputation is needed for this. My reputation is 7. I try to do this as soon as I'm able to vote. – Questioner Jun 20 '15 at 18:46
  • 2
    Is there way to use without "BC"? I wonder whether oracle jre has ECDSA algorithm for KeyFactory? – Hai Bi Apr 08 '18 at 02:24
  • how can I do this in C/C++? – uss May 27 '19 at 13:38
  • @HaiBi: Oracle Java 7 and up has the SunEC provider which has (one) `KeyFactory` named `EC` whose resulting keys are usable for both `ECDSA` and `ECDH` algorithms. And the same for `KeyPairGenerator`. – dave_thompson_085 Jun 01 '19 at 06:17