Codes to generate a public key in an elliptic curve algorithm using a given private key

后端 未结 4 878
天涯浪人
天涯浪人 2020-12-29 17:34

I need to implement ECC (Elliptic Curve Cryptography) algorithm using jdk 1.7. I tried using bouncy castle, sunEC, but all of them gave errors and errors. My target is to ge

4条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2020-12-29 17:57

    I wrote a sample program that outputs the following:

    FL261:java jvah$ javac -cp bcprov-ext-jdk15on-149.jar ECTest.java
    FL261:java jvah$ java -cp bcprov-ext-jdk15on-149.jar:. ECTest
    Private key: 7ba78909571fbc336b2b94054dfb745a6b0776ff36a8fa98a598dc32cb83cc8e
    Public key: 035b9e4a6148c9f9b08b573871ac66a832e6e9f63cf117545523a45b8017b7c43f
    Calculated public key: 035b9e4a6148c9f9b08b573871ac66a832e6e9f63cf117545523a45b8017b7c43f
    Congratulations, public keys match!
    FL261:java jvah$
    

    The code should be clear enough so that you can understand what is done here. Please note that you really have to know which curve your private key is generated for, otherwise it is impossible to generate the matching public key. The sample code uses secp256r1 curve, which is quite commonly used.

    import java.math.BigInteger;
    import java.security.SecureRandom;
    
    import org.bouncycastle.asn1.x9.X9ECParameters;
    import org.bouncycastle.asn1.sec.SECNamedCurves;
    import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    import org.bouncycastle.crypto.params.ECDomainParameters;
    import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
    import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
    import org.bouncycastle.crypto.params.ECPublicKeyParameters;
    import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
    import org.bouncycastle.math.ec.ECPoint;
    
    class ECTest {
      public static String toHex(byte[] data) {
        StringBuilder sb = new StringBuilder();
        for (byte b: data) {
          sb.append(String.format("%02x", b&0xff));
        }
        return sb.toString();
      }
    
      public static void main(String[] argv) {
        // Get domain parameters for example curve secp256r1
        X9ECParameters ecp = SECNamedCurves.getByName("secp256r1");
        ECDomainParameters domainParams = new ECDomainParameters(ecp.getCurve(),
                                                                 ecp.getG(), ecp.getN(), ecp.getH(),
                                                                 ecp.getSeed());
    
        // Generate a private key and a public key
        AsymmetricCipherKeyPair keyPair;
        ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, new SecureRandom());
        ECKeyPairGenerator generator = new ECKeyPairGenerator();
        generator.init(keyGenParams);
        keyPair = generator.generateKeyPair();
    
        ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate();
        ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic();
        byte[] privateKeyBytes = privateKey.getD().toByteArray();
    
        // First print our generated private key and public key
        System.out.println("Private key: " + toHex(privateKeyBytes));
        System.out.println("Public key: " + toHex(publicKey.getQ().getEncoded(true)));
    
        // Then calculate the public key only using domainParams.getG() and private key
        ECPoint Q = domainParams.getG().multiply(new BigInteger(privateKeyBytes));
        System.out.println("Calculated public key: " + toHex(Q.getEncoded(true)));
    
        // The calculated public key and generated public key should always match
        if (!toHex(publicKey.getQ().getEncoded(true)).equals(toHex(Q.getEncoded(true)))) {
          System.out.println("ERROR: Public keys do not match!");
        } else {
          System.out.println("Congratulations, public keys match!");
        }
      }
    }
    

提交回复
热议问题