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. This class is thread-safe. 018 * 019 * <p>Supports the following key management algorithms: 020 * 021 * <ul> 022 * <li>{@link com.nimbusds.jose.JWEAlgorithm#DIR} 023 * </ul> 024 * 025 * <p>Supports the following content encryption algorithms: 026 * 027 * <ul> 028 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256} 029 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384} 030 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512} 031 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128GCM} 032 * <li>{@link com.nimbusds.jose.EncryptionMethod#A192GCM} 033 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256GCM} 034 * <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256_DEPRECATED} 035 * <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512_DEPRECATED} 036 * </ul> 037 * 038 * @author Vladimir Dzhuvinov 039 * @version 2014-06-29 040 */ 041@ThreadSafe 042public class DirectEncrypter extends DirectCryptoProvider implements JWEEncrypter { 043 044 045 /** 046 * Creates a new direct encrypter. 047 * 048 * @param key The symmetric key. Its algorithm must be "AES". Must be 049 * 128 bits (16 bytes), 192 bits (24 bytes), 256 bits (32 050 * bytes), 384 bits (48 bytes) or 512 bits (64 bytes) long. 051 * Must not be {@code null}. 052 * 053 * @throws KeyLengthException If the symmetric key length is not 054 * compatible. 055 */ 056 public DirectEncrypter(final SecretKey key) 057 throws KeyLengthException { 058 059 super(key); 060 } 061 062 063 /** 064 * Creates a new direct encrypter. 065 * 066 * @param keyBytes The symmetric key, as a byte array. Must be 128 bits 067 * (16 bytes), 192 bits (24 bytes), 256 bits (32 068 * bytes), 384 bits (48 bytes) or 512 bits (64 bytes) 069 * long. Must not be {@code null}. 070 * 071 * @throws KeyLengthException If the symmetric key length is not 072 * compatible. 073 */ 074 public DirectEncrypter(final byte[] keyBytes) 075 throws KeyLengthException { 076 077 this(new SecretKeySpec(keyBytes, "AES")); 078 } 079 080 081 /** 082 * Creates a new direct encrypter. 083 * 084 * @param octJWK The symmetric key, as a JWK. Must be 128 bits (16 085 * bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384 086 * bits (48 bytes) or 512 bits (64 bytes) long. Must not 087 * be {@code null}. 088 * 089 * @throws KeyLengthException If the symmetric key length is not 090 * compatible. 091 */ 092 public DirectEncrypter(final OctetSequenceKey octJWK) 093 throws KeyLengthException { 094 095 this(octJWK.toSecretKey("AES")); 096 } 097 098 099 @Override 100 public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText) 101 throws JOSEException { 102 103 JWEAlgorithm alg = header.getAlgorithm(); 104 105 if (! alg.equals(JWEAlgorithm.DIR)) { 106 throw new JOSEException(AlgorithmSupportMessage.unsupportedJWEAlgorithm(alg, SUPPORTED_ALGORITHMS)); 107 } 108 109 // Check key length matches encryption method 110 EncryptionMethod enc = header.getEncryptionMethod(); 111 112 if (enc.cekBitLength() != ByteUtils.bitLength(getKey().getEncoded())) { 113 throw new KeyLengthException(enc.cekBitLength(), enc); 114 } 115 116 final Base64URL encryptedKey = null; // The second JWE part 117 118 return ContentCryptoProvider.encrypt(header, clearText, getKey(), encryptedKey, getJCAContext()); 119 } 120}