001package com.nimbusds.jose.crypto; 002 003 004import java.security.interfaces.RSAPublicKey; 005import javax.crypto.SecretKey; 006 007import net.jcip.annotations.ThreadSafe; 008 009import com.nimbusds.jose.EncryptionMethod; 010import com.nimbusds.jose.JOSEException; 011import com.nimbusds.jose.JWEAlgorithm; 012import com.nimbusds.jose.JWECryptoParts; 013import com.nimbusds.jose.JWEEncrypter; 014import com.nimbusds.jose.JWEHeader; 015import com.nimbusds.jose.jwk.RSAKey; 016import com.nimbusds.jose.util.Base64URL; 017 018 019/** 020 * RSA encrypter of {@link com.nimbusds.jose.JWEObject JWE objects}. This class 021 * is thread-safe. 022 * 023 * <p>Supports the following key management algorithms: 024 * 025 * <ul> 026 * <li>{@link com.nimbusds.jose.JWEAlgorithm#RSA1_5} 027 * <li>{@link com.nimbusds.jose.JWEAlgorithm#RSA_OAEP} 028 * <li>{@link com.nimbusds.jose.JWEAlgorithm#RSA_OAEP_256} 029 * </ul> 030 * 031 * <p>Supports the following content encryption algorithms: 032 * 033 * <ul> 034 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256} 035 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384} 036 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512} 037 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128GCM} 038 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192GCM} 039 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256GCM} 040 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256_DEPRECATED} 041 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512_DEPRECATED} 042 * </ul> 043 * 044 * @author David Ortiz 045 * @author Vladimir Dzhuvinov 046 * @version 2015-06-08 047 */ 048@ThreadSafe 049public class RSAEncrypter extends RSACryptoProvider implements JWEEncrypter { 050 051 052 /** 053 * The public RSA key. 054 */ 055 private final RSAPublicKey publicKey; 056 057 058 /** 059 * Creates a new RSA encrypter. 060 * 061 * @param publicKey The public RSA key. Must not be {@code null}. 062 */ 063 public RSAEncrypter(final RSAPublicKey publicKey) { 064 065 if (publicKey == null) { 066 throw new IllegalArgumentException("The public RSA key must not be null"); 067 } 068 069 this.publicKey = publicKey; 070 } 071 072 073 /** 074 * Creates a new RSA encrypter. 075 * 076 * @param rsaJWK The RSA JSON Web Key (JWK). Must not be {@code null}. 077 * 078 * @throws JOSEException If the RSA JWK extraction failed. 079 */ 080 public RSAEncrypter(final RSAKey rsaJWK) 081 throws JOSEException { 082 083 this(rsaJWK.toRSAPublicKey()); 084 } 085 086 087 /** 088 * Gets the public RSA key. 089 * 090 * @return The public RSA key. 091 */ 092 public RSAPublicKey getPublicKey() { 093 094 return publicKey; 095 } 096 097 098 @Override 099 public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText) 100 throws JOSEException { 101 102 final JWEAlgorithm alg = header.getAlgorithm(); 103 final EncryptionMethod enc = header.getEncryptionMethod(); 104 105 // Generate and encrypt the CEK according to the enc method 106 final SecretKey cek = ContentCryptoProvider.generateCEK(enc, getJCAContext().getSecureRandom()); 107 108 final Base64URL encryptedKey; // The second JWE part 109 110 if (alg.equals(JWEAlgorithm.RSA1_5)) { 111 112 encryptedKey = Base64URL.encode(RSA1_5.encryptCEK(publicKey, cek, getJCAContext().getKeyEncryptionProvider())); 113 114 } else if (alg.equals(JWEAlgorithm.RSA_OAEP)) { 115 116 encryptedKey = Base64URL.encode(RSA_OAEP.encryptCEK(publicKey, cek, getJCAContext().getKeyEncryptionProvider())); 117 118 } else if (alg.equals(JWEAlgorithm.RSA_OAEP_256)) { 119 120 encryptedKey = Base64URL.encode(RSA_OAEP_256.encryptCEK(publicKey, cek, getJCAContext().getKeyEncryptionProvider())); 121 122 } else { 123 124 throw new JOSEException(AlgorithmSupportMessage.unsupportedJWEAlgorithm(alg, SUPPORTED_ALGORITHMS)); 125 } 126 127 return ContentCryptoProvider.encrypt(header, clearText, cek, encryptedKey, getJCAContext()); 128 } 129}