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.crypto.impl; 019 020 021import com.nimbusds.jose.EncryptionMethod; 022import com.nimbusds.jose.JWEAlgorithm; 023import com.nimbusds.jose.KeyLengthException; 024import com.nimbusds.jose.util.ByteUtils; 025 026import javax.crypto.SecretKey; 027import java.util.Collections; 028import java.util.LinkedHashSet; 029import java.util.Set; 030 031 032/** 033 * The base abstract class for direct encrypters and decrypters of 034 * {@link com.nimbusds.jose.JWEObject JWE objects} with a shared symmetric key. 035 * 036 * <p>Supports the following key management algorithms: 037 * 038 * <ul> 039 * <li>{@link com.nimbusds.jose.JWEAlgorithm#DIR} 040 * </ul> 041 * 042 * <p>Supports the following content encryption algorithms: 043 * 044 * <ul> 045 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256} 046 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384} 047 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512} 048 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128GCM} 049 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192GCM} 050 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256GCM} 051 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256_DEPRECATED} 052 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512_DEPRECATED} 053 * <li>{@link com.nimbusds.jose.EncryptionMethod#XC20P} 054 * </ul> 055 * 056 * @author Vladimir Dzhuvinov 057 * @version 2023-07-11 058 */ 059public abstract class DirectCryptoProvider extends BaseJWEProvider { 060 061 062 /** 063 * The supported JWE algorithms by the direct crypto provider class. 064 */ 065 public static final Set<JWEAlgorithm> SUPPORTED_ALGORITHMS; 066 067 068 /** 069 * The supported encryption methods by the direct crypto provider 070 * class. 071 */ 072 public static final Set<EncryptionMethod> SUPPORTED_ENCRYPTION_METHODS = ContentCryptoProvider.SUPPORTED_ENCRYPTION_METHODS; 073 074 075 static { 076 Set<JWEAlgorithm> algs = new LinkedHashSet<>(); 077 algs.add(JWEAlgorithm.DIR); 078 SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs); 079 } 080 081 082 /** 083 * Returns the compatible encryption methods for the specified Content 084 * Encryption Key (CEK) length. 085 * 086 * @param cekBitLength The CEK length in bits. 087 * 088 * @return The compatible encryption methods. 089 * 090 * @throws KeyLengthException If the CEK length is not compatible. 091 */ 092 private static Set<EncryptionMethod> getCompatibleEncryptionMethods(final int cekBitLength) 093 throws KeyLengthException { 094 095 if (cekBitLength == 0) { 096 // Suspect HSM that doesn't expose key material, return all supported enc AES/GCM methods 097 // https://bitbucket.org/connect2id/nimbus-jose-jwt/issues/490/jwe-with-shared-key-support-for-android 098 return EncryptionMethod.Family.AES_GCM; 099 } 100 101 Set<EncryptionMethod> encs = ContentCryptoProvider.COMPATIBLE_ENCRYPTION_METHODS.get(cekBitLength); 102 103 if (encs == null) { 104 throw new KeyLengthException("The Content Encryption Key length must be 128 bits (16 bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384 bits (48 bytes) or 512 bites (64 bytes)"); 105 } 106 107 return encs; 108 } 109 110 111 /** 112 * Creates a new direct encryption / decryption provider. 113 * 114 * @param cek The Content Encryption Key (CEK). Must be 128 bits (16 115 * bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384 116 * bits (48 bytes) or 512 bits (64 bytes) long. Must not be 117 * {@code null}. 118 * 119 * @throws KeyLengthException If the CEK length is not compatible. 120 */ 121 protected DirectCryptoProvider(final SecretKey cek) 122 throws KeyLengthException { 123 124 super(SUPPORTED_ALGORITHMS, getCompatibleEncryptionMethods(ByteUtils.bitLength(cek.getEncoded())), cek); 125 } 126 127 128 /** 129 * Gets the Content Encryption Key (CEK). 130 * 131 * @return The key. 132 */ 133 public SecretKey getKey() { 134 try { 135 return getCEK(null); 136 } catch (Exception e) { 137 return null; 138 } 139 } 140}