001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
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 javax.crypto.SecretKey;
022import javax.crypto.spec.SecretKeySpec;
023
024import com.nimbusds.jose.crypto.impl.*;
025import net.jcip.annotations.ThreadSafe;
026
027import com.nimbusds.jose.*;
028import com.nimbusds.jose.jwk.OctetSequenceKey;
029import com.nimbusds.jose.util.Base64URL;
030
031
032/**
033 * Direct encrypter of {@link com.nimbusds.jose.JWEObject JWE objects} with a
034 * shared symmetric key.
035 *
036 * <p>See RFC 7518
037 * <a href="https://tools.ietf.org/html/rfc7518#section-4.5">section 4.5</a>
038 * for more information.</p>
039 *
040 * <p>This class is thread-safe.
041 *
042 * <p>Supports the following key management algorithms:
043 *
044 * <ul>
045 *     <li>{@link com.nimbusds.jose.JWEAlgorithm#DIR}
046 * </ul>
047 *
048 * <p>Supports the following content encryption algorithms:
049 *
050 * <ul>
051 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256} (requires 256 bit key)
052 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384} (requires 384 bit key)
053 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512} (requires 512 bit key)
054 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A128GCM} (requires 128 bit key)
055 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A192GCM} (requires 192 bit key)
056 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A256GCM} (requires 256 bit key)
057 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256_DEPRECATED} (requires 256 bit key)
058 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512_DEPRECATED} (requires 512 bit key)
059 *     <li>{@link com.nimbusds.jose.EncryptionMethod#XC20P} (requires 256 bit key)
060 * </ul>
061 *
062 * @author Vladimir Dzhuvinov
063 * @author Egor Puzanov
064 * @version 2023-09-10
065 */
066@ThreadSafe
067public class DirectEncrypter extends DirectCryptoProvider implements JWEEncrypter {
068
069
070        /**
071         * Creates a new direct encrypter.
072         *
073         * @param key The symmetric key. Its algorithm should be "AES". Must be
074         *            128 bits (16 bytes), 192 bits (24 bytes), 256 bits (32
075         *            bytes), 384 bits (48 bytes) or 512 bits (64 bytes) long.
076         *            Must not be {@code null}.
077         *
078         * @throws KeyLengthException If the symmetric key length is not
079         *                            compatible.
080         */
081        public DirectEncrypter(final SecretKey key)
082                throws KeyLengthException {
083
084                super(key);
085        }
086
087
088        /**
089         * Creates a new direct encrypter.
090         *
091         * @param keyBytes The symmetric key, as a byte array. Must be 128 bits
092         *                 (16 bytes), 192 bits (24 bytes), 256 bits (32
093         *                 bytes), 384 bits (48 bytes) or 512 bits (64 bytes)
094         *                 long. Must not be {@code null}.
095         *
096         * @throws KeyLengthException If the symmetric key length is not
097         *                            compatible.
098         */
099        public DirectEncrypter(final byte[] keyBytes)
100                throws KeyLengthException {
101
102                this(new SecretKeySpec(keyBytes, "AES"));
103        }
104
105
106        /**
107         * Creates a new direct encrypter.
108         *
109         * @param octJWK The symmetric key, as a JWK. Must be 128 bits (16
110         *               bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384
111         *               bits (48 bytes) or 512 bits (64 bytes) long. Must not
112         *               be {@code null}.
113         *
114         * @throws KeyLengthException If the symmetric key length is not
115         *                            compatible.
116         */
117        public DirectEncrypter(final OctetSequenceKey octJWK)
118                throws KeyLengthException {
119
120                this(octJWK.toSecretKey("AES"));
121        }
122
123
124        /**
125         * Encrypts the specified clear text of a {@link JWEObject JWE object}.
126         *
127         * @param header    The JSON Web Encryption (JWE) header. Must specify
128         *                  a supported JWE algorithm and method. Must not be
129         *                  {@code null}.
130         * @param clearText The clear text to encrypt. Must not be {@code null}.
131         *
132         * @return The resulting JWE crypto parts.
133         *
134         * @throws JOSEException If the JWE algorithm or method is not
135         *                       supported or if encryption failed for some
136         *                       other internal reason.
137         */
138        @Deprecated
139        public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText)
140                throws JOSEException {
141
142                return encrypt(header, clearText, AAD.compute(header));
143        }
144
145
146        @Override
147        public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText, final byte[] aad)
148                throws JOSEException {
149
150                final JWEAlgorithm alg = JWEHeaderValidation.getAlgorithmAndEnsureNotNull(header);
151
152                if (! alg.equals(JWEAlgorithm.DIR)) {
153                        throw new JOSEException(AlgorithmSupportMessage.unsupportedJWEAlgorithm(alg, SUPPORTED_ALGORITHMS));
154                }
155
156                final Base64URL encryptedKey = null; // The second JWE part
157
158                return ContentCryptoProvider.encrypt(header, clearText, aad, getKey(), encryptedKey, getJCAContext());
159        }
160}