001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2021, 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.crypto; 019 020 021import com.nimbusds.jose.*; 022import com.nimbusds.jose.crypto.impl.*; 023import com.nimbusds.jose.jwk.Curve; 024import com.nimbusds.jose.jwk.OctetKeyPair; 025import com.nimbusds.jose.util.Base64URL; 026import net.jcip.annotations.ThreadSafe; 027 028import javax.crypto.SecretKey; 029import java.util.Collections; 030import java.util.Set; 031 032 033/** 034 * Elliptic Curve Diffie-Hellman decrypter of 035 * {@link com.nimbusds.jose.JWEObject JWE objects} for curves using an OKP JWK. 036 * Expects a private {@link OctetKeyPair} key with {@code "crv"} X25519. 037 * 038 * <p>See <a href="https://tools.ietf.org/html/rfc8037">RFC 8037</a> 039 * for more information. 040 * 041 * <p>See also {@link ECDH1PUDecrypter} for ECDH on other curves. 042 * 043 * <p>Public Key Authenticated Encryption for JOSE 044 * <a href="https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04">ECDH-1PU</a> 045 * for more information. 046 * 047 * <p>This class is thread-safe. 048 * 049 * <p>Supports the following key management algorithms: 050 * 051 * <ul> 052 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_1PU} 053 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_1PU_A128KW} 054 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_1PU_A192KW} 055 * <li>{@link com.nimbusds.jose.JWEAlgorithm#ECDH_1PU_A256KW} 056 * </ul> 057 * 058 * <p>Supports the following elliptic curves: 059 * 060 * <ul> 061 * <li>{@link Curve#X25519} 062 * </ul> 063 * 064 * <p>Supports the following content encryption algorithms for Direct key 065 * agreement mode: 066 * 067 * <ul> 068 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256} 069 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384} 070 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512} 071 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128GCM} 072 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192GCM} 073 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256GCM} 074 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256_DEPRECATED} 075 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512_DEPRECATED} 076 * <li>{@link com.nimbusds.jose.EncryptionMethod#XC20P} 077 * </ul> 078 * 079 * <p>Supports the following content encryption algorithms for Key wrapping 080 * mode: 081 * 082 * <ul> 083 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256} 084 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384} 085 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512} 086 * </ul> 087 * 088 * @author Alexander Martynov 089 * @author Egor Puzanov 090 * @version 2023-05-17 091 */ 092@ThreadSafe 093public class ECDH1PUX25519Decrypter extends ECDH1PUCryptoProvider implements JWEDecrypter, CriticalHeaderParamsAware { 094 095 096 /** 097 * The private key. 098 */ 099 private final OctetKeyPair privateKey; 100 101 /** 102 * The public key. 103 */ 104 private final OctetKeyPair publicKey; 105 106 /** 107 * The critical header policy. 108 */ 109 private final CriticalHeaderParamsDeferral critPolicy = new CriticalHeaderParamsDeferral(); 110 111 112 /** 113 * Creates a new Curve25519 Elliptic Curve Diffie-Hellman decrypter. 114 * 115 * @param privateKey The private key. Must not be {@code null}. 116 * @param publicKey The private key. Must not be {@code null}. 117 * 118 * @throws JOSEException If the key subtype is not supported. 119 */ 120 public ECDH1PUX25519Decrypter(final OctetKeyPair privateKey, final OctetKeyPair publicKey) 121 throws JOSEException { 122 123 this(privateKey, publicKey, null); 124 } 125 126 127 /** 128 * Creates a new Curve25519 Elliptic Curve Diffie-Hellman decrypter. 129 * 130 * @param privateKey The private key. Must not be {@code null}. 131 * @param publicKey The private key. Must not be {@code null}. 132 * @param defCritHeaders The names of the critical header parameters 133 * that are deferred to the application for 134 * processing, empty set or {@code null} if none. 135 * 136 * @throws JOSEException If the key subtype is not supported. 137 */ 138 public ECDH1PUX25519Decrypter(final OctetKeyPair privateKey, 139 final OctetKeyPair publicKey, 140 final Set<String> defCritHeaders) 141 throws JOSEException { 142 143 super(privateKey.getCurve(), null); 144 145 this.privateKey = privateKey; 146 this.publicKey = publicKey; 147 148 critPolicy.setDeferredCriticalHeaderParams(defCritHeaders); 149 } 150 151 152 @Override 153 public Set<Curve> supportedEllipticCurves() { 154 155 return Collections.singleton(Curve.X25519); 156 } 157 158 159 /** 160 * Returns the private key. 161 * 162 * @return The private key. 163 */ 164 public OctetKeyPair getPrivateKey() { 165 166 return privateKey; 167 } 168 169 /** 170 * Returns the public key. 171 * 172 * @return The public key. 173 */ 174 public OctetKeyPair getPublicKey() { 175 176 return publicKey; 177 } 178 179 @Override 180 public Set<String> getProcessedCriticalHeaderParams() { 181 182 return critPolicy.getProcessedCriticalHeaderParams(); 183 } 184 185 186 @Override 187 public Set<String> getDeferredCriticalHeaderParams() { 188 189 return critPolicy.getProcessedCriticalHeaderParams(); 190 } 191 192 193 /** 194 * Decrypts the specified cipher text of a {@link JWEObject JWE Object}. 195 * 196 * @param header The JSON Web Encryption (JWE) header. Must 197 * specify a supported JWE algorithm and method. 198 * Must not be {@code null}. 199 * @param encryptedKey The encrypted key, {@code null} if not required 200 * by the JWE algorithm. 201 * @param iv The initialisation vector, {@code null} if not 202 * required by the JWE algorithm. 203 * @param cipherText The cipher text to decrypt. Must not be 204 * {@code null}. 205 * @param authTag The authentication tag, {@code null} if not 206 * required. 207 * 208 * @return The clear text. 209 * 210 * @throws JOSEException If the JWE algorithm or method is not 211 * supported, if a critical header parameter is 212 * not supported or marked for deferral to the 213 * application, or if decryption failed for some 214 * other reason. 215 */ 216 @Deprecated 217 public byte[] decrypt(final JWEHeader header, 218 final Base64URL encryptedKey, 219 final Base64URL iv, 220 final Base64URL cipherText, 221 final Base64URL authTag) 222 throws JOSEException { 223 224 return decrypt(header, encryptedKey, iv, cipherText, authTag, AAD.compute(header)); 225 } 226 227 228 @Override 229 public byte[] decrypt(final JWEHeader header, 230 final Base64URL encryptedKey, 231 final Base64URL iv, 232 final Base64URL cipherText, 233 final Base64URL authTag, 234 final byte[] aad) 235 throws JOSEException { 236 237 // Check for unrecognizable "crit" properties 238 critPolicy.ensureHeaderPasses(header); 239 240 // Get ephemeral key from header 241 OctetKeyPair ephemeralPublicKey = (OctetKeyPair) header.getEphemeralPublicKey(); 242 243 if (ephemeralPublicKey == null) { 244 throw new JOSEException("Missing ephemeral public key \"epk\" JWE header parameter"); 245 } 246 247 SecretKey Z = ECDH1PU.deriveRecipientZ( 248 privateKey, 249 publicKey, 250 ephemeralPublicKey 251 ); 252 253 return decryptWithZ(header, aad, Z, encryptedKey, iv, cipherText, authTag); 254 } 255}