Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
158 views
in Technique[技术] by (71.8m points)

node.js - Trying to create a ECDH keypair in Java

I am needing to migrate some simple KeyPair creation from Javascript to Java. Using the NodeJS crypto package, this was extremely simple:

const keyPair = crypto.createECDH("prime256v1");
keyPair.generateKeys();

You can then use the generated keyPair to generate public and private keys to exchange data with our server.

I have found several code samples written in Java that generate ECDH Key Pairs using BouncyCastle, but they all throw the following exception:

java.security.InvalidKeyException: No installed provider supports this key: org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey

It would seem this should be as trivial as it was in Node. What am I missing?

I tried the suggested code, and I'm getting the [similar] exception:

java.security.InvalidKeyException: No installed provider supports this key: sun.security.ec.ECPrivateKeyImpl
        at javax.crypto.Cipher.chooseProvider(Cipher.java:896)
        at javax.crypto.Cipher.init(Cipher.java:1399)
        at javax.crypto.Cipher.init(Cipher.java:1330)
        at com.strivve.Encryption.encryptAES256(Encryption.java:42)
        at com.strivve.App.go(App.java:26)
        at com.strivve.App.main(App.java:14)
question from:https://stackoverflow.com/questions/66060346/trying-to-create-a-ecdh-keypair-in-java

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's nearly easy as in NodeJs to generate an ECDH key pair, but you need to know the curve name used in Java. The curve "prime256v1" is known in Java with "secp256r1" and the SunEC crypto provider has an implementation for it.

This is a result of the program below (Java print outs the synonym curve names in detail):

Java generate an EC keypair
privateKey: sun.security.ec.ECPrivateKeyImpl@ffff97b7
publicKey: Sun EC public key, 256 bits
  public x coord: 41232853336475799847910994406242230229392118856956796272263514934771986125833
  public y coord: 39545744123202785115112968739657610229201870815399428487100236626986481235670
  parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)

full code without any exception handling:

import java.security.*;
import java.security.spec.ECGenParameterSpec;

public class Main {
    public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        System.out.println("Java generate an EC keypair");
        String ecdhCurvenameString = "secp256r1";
        // standard curvennames
        // secp256r1 [NIST P-256, X9.62 prime256v1]
        // secp384r1 [NIST P-384]
        // secp521r1 [NIST P-521]
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "SunEC");
        ECGenParameterSpec ecParameterSpec = new ECGenParameterSpec(ecdhCurvenameString);
        keyPairGenerator.initialize(ecParameterSpec);
        KeyPair ecdhKeyPair = keyPairGenerator.genKeyPair();
        PrivateKey privateKey = ecdhKeyPair.getPrivate();
        PublicKey publicKey = ecdhKeyPair.getPublic();
        System.out.println("privateKey: " + privateKey);
        System.out.println("publicKey: " + publicKey);
    }
}

Edit: Feb. 7th 2021: The code runs on Open Java 11 that has the SunEC provider included, that's why you don't see any additional library to import. Maybe your Java does not include the provider or it is disabled, kindly run my simple provider test - this is the result on Java 11:

Provider: SUN version: 11.0
Provider: SunRsaSign version: 11.0
Provider: SunEC version: 11.0
Provider: SunJSSE version: 11.0
Provider: SunJCE version: 11.0
Provider: SunJGSS version: 11.0
Provider: SunSASL version: 11.0
Provider: XMLDSig version: 11.0
Provider: SunPCSC version: 11.0
Provider: JdkLDAP version: 11.0
Provider: JdkSASL version: 11.0
Provider: SunPKCS11 version: 11.0

code:

import java.security.Provider;
import java.security.Security;
 
public class A05_CryptoProvider {
    
    public static void main(String[] args) {
        // source https://stackoverflow.com/questions/3683302/how-to-find-out-what-algorithm-encryption-are-supported-by-my-jvm/3683915#3683915
        for (Provider provider : Security.getProviders()) {
            System.out.println("Provider: " + provider.getName() + " version: " + provider.getVersion());
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...