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 java.security.KeyPair; 022import java.security.KeyPairGenerator; 023import java.security.NoSuchAlgorithmException; 024import java.security.interfaces.RSAPublicKey; 025 026import com.nimbusds.jose.JOSEException; 027import com.nimbusds.jose.jwk.RSAKey; 028 029 030/** 031 * RSA JSON Web Key (JWK) generator. 032 * 033 * @author Vladimir Dzhuvinov 034 * @author Justin Cranford 035 * @version 2022-09-13 036 */ 037public class RSAKeyGenerator extends JWKGenerator<RSAKey> { 038 039 040 /** 041 * The minimum size of generated keys. 042 */ 043 public static final int MIN_KEY_SIZE_BITS = 2048; 044 045 046 /** 047 * The RSA key size, in bits. 048 */ 049 private final int size; 050 051 052 /** 053 * Creates a new RSA JWK generator. 054 * 055 * @param size The RSA key size, in bits. Must be at least 2048 bits 056 * long for sufficient strength. 057 */ 058 public RSAKeyGenerator(final int size) { 059 060 this(size, false); 061 } 062 063 064 /** 065 * Creates a new RSA JWK generator. 066 * 067 * @param size The RSA key size, in bits. Must be at least 068 * 2048 bits long for sufficient strength. 069 * @param allowWeakKeys {@code true} to allow generation of keys 070 * shorter than 2048 bits. 071 */ 072 public RSAKeyGenerator(final int size, final boolean allowWeakKeys) { 073 074 if (! allowWeakKeys && size < MIN_KEY_SIZE_BITS) { 075 throw new IllegalArgumentException("The key size must be at least " + MIN_KEY_SIZE_BITS + " bits"); 076 } 077 this.size = size; 078 } 079 080 081 @Override 082 public RSAKey generate() 083 throws JOSEException { 084 085 KeyPairGenerator generator; 086 try { 087 if (keyStore != null) { 088 // For PKCS#11 089 generator = KeyPairGenerator.getInstance("RSA", keyStore.getProvider()); 090 } else { 091 generator = KeyPairGenerator.getInstance("RSA"); 092 } 093 if (secureRandom != null) { 094 generator.initialize(size, secureRandom); 095 } else { 096 // The default random gen 097 generator.initialize(size); 098 } 099 } catch (NoSuchAlgorithmException e) { 100 throw new JOSEException(e.getMessage(), e); 101 } 102 103 KeyPair kp = generator.generateKeyPair(); 104 105 RSAKey.Builder builder = new RSAKey.Builder((RSAPublicKey) kp.getPublic()) 106 .privateKey(kp.getPrivate()) 107 .keyUse(use) 108 .keyOperations(ops) 109 .algorithm(alg) 110 .keyStore(keyStore); 111 112 if (x5tKid) { 113 builder.keyIDFromThumbprint(); 114 } else { 115 builder.keyID(kid); 116 } 117 118 return builder.build(); 119 } 120}