001package com.nimbusds.jose.crypto; 002 003 004import javax.crypto.SecretKey; 005import javax.crypto.spec.SecretKeySpec; 006 007import net.jcip.annotations.ThreadSafe; 008 009import com.nimbusds.jose.*; 010import com.nimbusds.jose.jwk.OctetSequenceKey; 011import com.nimbusds.jose.util.Base64URL; 012import com.nimbusds.jose.util.ByteUtils; 013 014 015/** 016 * Direct encrypter of {@link com.nimbusds.jose.JWEObject JWE objects} with a 017 * shared symmetric key. 018 * 019 * <p>See RFC 7518 020 * <a href="https://tools.ietf.org/html/rfc7518#section-4.5">section 4.5</a> 021 * for more information.</p> 022 * 023 * <p>This class is thread-safe. 024 * 025 * <p>Supports the following key management algorithms: 026 * 027 * <ul> 028 * <li>{@link com.nimbusds.jose.JWEAlgorithm#DIR} 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 Vladimir Dzhuvinov 045 * @version 2014-06-29 046 */ 047@ThreadSafe 048public class DirectEncrypter extends DirectCryptoProvider implements JWEEncrypter { 049 050 051 /** 052 * Creates a new direct encrypter. 053 * 054 * @param key The symmetric key. Its algorithm must be "AES". Must be 055 * 128 bits (16 bytes), 192 bits (24 bytes), 256 bits (32 056 * bytes), 384 bits (48 bytes) or 512 bits (64 bytes) long. 057 * Must not be {@code null}. 058 * 059 * @throws KeyLengthException If the symmetric key length is not 060 * compatible. 061 */ 062 public DirectEncrypter(final SecretKey key) 063 throws KeyLengthException { 064 065 super(key); 066 } 067 068 069 /** 070 * Creates a new direct encrypter. 071 * 072 * @param keyBytes The symmetric key, as a byte array. Must be 128 bits 073 * (16 bytes), 192 bits (24 bytes), 256 bits (32 074 * bytes), 384 bits (48 bytes) or 512 bits (64 bytes) 075 * long. Must not be {@code null}. 076 * 077 * @throws KeyLengthException If the symmetric key length is not 078 * compatible. 079 */ 080 public DirectEncrypter(final byte[] keyBytes) 081 throws KeyLengthException { 082 083 this(new SecretKeySpec(keyBytes, "AES")); 084 } 085 086 087 /** 088 * Creates a new direct encrypter. 089 * 090 * @param octJWK The symmetric key, as a JWK. Must be 128 bits (16 091 * bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384 092 * bits (48 bytes) or 512 bits (64 bytes) long. Must not 093 * be {@code null}. 094 * 095 * @throws KeyLengthException If the symmetric key length is not 096 * compatible. 097 */ 098 public DirectEncrypter(final OctetSequenceKey octJWK) 099 throws KeyLengthException { 100 101 this(octJWK.toSecretKey("AES")); 102 } 103 104 105 @Override 106 public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText) 107 throws JOSEException { 108 109 JWEAlgorithm alg = header.getAlgorithm(); 110 111 if (! alg.equals(JWEAlgorithm.DIR)) { 112 throw new JOSEException(AlgorithmSupportMessage.unsupportedJWEAlgorithm(alg, SUPPORTED_ALGORITHMS)); 113 } 114 115 // Check key length matches encryption method 116 EncryptionMethod enc = header.getEncryptionMethod(); 117 118 if (enc.cekBitLength() != ByteUtils.bitLength(getKey().getEncoded())) { 119 throw new KeyLengthException(enc.cekBitLength(), enc); 120 } 121 122 final Base64URL encryptedKey = null; // The second JWE part 123 124 return ContentCryptoProvider.encrypt(header, clearText, getKey(), encryptedKey, getJCAContext()); 125 } 126}