001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.jose.jwk.gen; 019 020 021import com.nimbusds.jose.JOSEException; 022import com.nimbusds.jose.jwk.Curve; 023import com.nimbusds.jose.jwk.ECKey; 024 025import java.security.InvalidAlgorithmParameterException; 026import java.security.KeyPair; 027import java.security.KeyPairGenerator; 028import java.security.NoSuchAlgorithmException; 029import java.security.interfaces.ECPublicKey; 030import java.security.spec.ECParameterSpec; 031import java.util.Objects; 032 033 034/** 035 * Elliptic Curve (EC) JSON Web Key (JWK) generator. 036 * 037 * <p>Supported curves: 038 * 039 * <ul> 040 * <li>{@link Curve#P_256 P-256} 041 * <li>{@link Curve#SECP256K1 secp256k1} 042 * <li>{@link Curve#P_384 P-384} 043 * <li>{@link Curve#P_521 P-512} 044 * </ul> 045 * 046 * @author Vladimir Dzhuvinov 047 * @author Justin Cranford 048 * @version 2024-12-15 049 */ 050public class ECKeyGenerator extends JWKGenerator<ECKey> { 051 052 053 /** 054 * The curve. 055 */ 056 private final Curve crv; 057 058 059 /** 060 * Creates a new EC JWK generator. 061 * 062 * @param crv The curve. Must not be {@code null}. 063 */ 064 public ECKeyGenerator(final Curve crv) { 065 this.crv = Objects.requireNonNull(crv); 066 } 067 068 069 @Override 070 public ECKey generate() 071 throws JOSEException { 072 073 ECParameterSpec ecSpec = crv.toECParameterSpec(); 074 075 KeyPairGenerator generator; 076 try { 077 if (keyStore != null) { 078 // For PKCS#11 079 generator = KeyPairGenerator.getInstance("EC", keyStore.getProvider()); 080 } else if (provider != null) { 081 generator = KeyPairGenerator.getInstance("EC", provider); 082 } else { 083 generator = KeyPairGenerator.getInstance("EC"); 084 } 085 if (secureRandom != null) { 086 generator.initialize(ecSpec, secureRandom); 087 } else { 088 // The default random gen 089 generator.initialize(ecSpec); 090 } 091 } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException e) { 092 throw new JOSEException(e.getMessage(), e); 093 } 094 095 KeyPair kp = generator.generateKeyPair(); 096 097 ECKey.Builder builder = new ECKey.Builder(crv, (ECPublicKey) kp.getPublic()) 098 .privateKey(kp.getPrivate()) 099 .keyUse(use) 100 .keyOperations(ops) 101 .algorithm(alg) 102 .expirationTime(exp) 103 .notBeforeTime(nbf) 104 .issueTime(iat) 105 .keyStore(keyStore); 106 107 if (tprKid) { 108 builder.keyIDFromThumbprint(); 109 } else { 110 builder.keyID(kid); 111 } 112 113 return builder.build(); 114 } 115}