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