org.picketlink.json.jose.crypto.JWEEncrypter Maven / Gradle / Ivy
Go to download
PicketLink JSON provides an API and implementation for JSON based on related specifications such as JWT, JWS and JWE.
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.picketlink.json.jose.crypto;
import static org.picketlink.json.JsonConstants.JWE.ALG_RSA1_5;
import static org.picketlink.json.JsonConstants.JWE.ALG_RSA_OAEP;
import static org.picketlink.json.JsonConstants.JWE.ALG_RSA_OAEP_256;
import static org.picketlink.json.JsonConstants.JWE.ENC_A128CBC_HS256;
import static org.picketlink.json.JsonConstants.JWE.ENC_A128GCM;
import static org.picketlink.json.JsonConstants.JWE.ENC_A192CBC_HS384;
import static org.picketlink.json.JsonConstants.JWE.ENC_A192GCM;
import static org.picketlink.json.JsonConstants.JWE.ENC_A256CBC_HS512;
import static org.picketlink.json.JsonConstants.JWE.ENC_A256GCM;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.SecretKey;
import org.picketlink.json.jose.JWE;
import org.picketlink.json.util.Base64Util;
/**
* JWE Encrypter of for JSON Web Encryption.
*
*
* Supports the following JWE algorithms:
*
*
* - {@link org.picketlink.json.JsonConstants.JWE.RSA1_5}
*
- {@link org.picketlink.json.JsonConstants.JWE.RSA_OAEP}
*
- {@link org.picketlink.json.JsonConstants.JWE.RSA_OAEP_256}
*
*
*
* Supports the following encryption algorithms:
*
*
* - {@link org.picketlink.json.JsonConstants.JWE.A128CBC_HS256}
*
- {@link org.picketlink.json.JsonConstants.JWE.A192CBC_HS384}
*
- {@link org.picketlink.json.JsonConstants.JWE.A256CBC_HS512}
*
- {@link org.picketlink.json.JsonConstants.JWE.A128GCM}
*
- {@link org.picketlink.json.JsonConstants.JWE.A192GCM}
*
- {@link org.picketlink.json.JsonConstants.JWE.A256GCM}
*
- {@link org.picketlink.json.JsonConstants.JWE.A128CBC_HS256_DEPRECATED}
*
- {@link org.picketlink.json.JsonConstants.JWE.A256CBC_HS512_DEPRECATED}
*
*
* @author Giriraj Sharma
*/
public class JWEEncrypter {
/**
* The public RSA key.
*/
private final RSAPublicKey publicKey;
/**
* Creates a new JWE encrypter.
*
* @param publicKey The public RSA key. Must not be {@code null}.
*
* @throws RuntimeException If the underlying secure random generator couldn't be instantiated.
*/
public JWEEncrypter(final RSAPublicKey publicKey) {
if (publicKey == null) {
throw new IllegalArgumentException("The public RSA key must not be null");
}
this.publicKey = publicKey;
}
/**
* Gets the public RSA key.
*
* @return The public RSA key.
*/
public RSAPublicKey getPublicKey() {
return publicKey;
}
/**
* Creates a JWE compact serialization.This string is BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWEEncrypted
* Key) || '.' || BASE64URL(JWE Initialization Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' ||
* BASE64URL(JWEAuthentication Tag).
*
* @param jweHeader The JWE Header. Must not be {@code null}.
* @param bytes The byte array of message to be encrypted. Must not be {@code null}.
*
* @return The compact serialization string.
*
* @throws RuntimeException If any of the algorithm is unsupported.
*/
public String encrypt(JWE jweHeader, final byte[] bytes) {
final String alg = jweHeader.getAlgorithm();
final String enc = jweHeader.getEncryptionAlgorithm();
// Generate and encrypt the CEK according to the enc method
final SecureRandom randomGen = new SecureRandom();
final SecretKey cek = AES.generateKey(Integer.parseInt(jweHeader.getCEKBitLength()), randomGen);
byte[] encryptedKey;
if (alg.equals(ALG_RSA1_5)) {
encryptedKey = RSA1_5.encryptCEK(publicKey, cek);
} else if (alg.equals(ALG_RSA_OAEP)) {
encryptedKey = RSA_OAEP.encryptCEK(publicKey, cek);
} else if (alg.equals(ALG_RSA_OAEP_256)) {
encryptedKey = RSA_OAEP_256.encryptCEK(publicKey, cek);
} else {
throw new RuntimeException("Unsupported JWE algorithm, must be RSA1_5, RSA-OAEP, or RSA-OAEP-256");
}
// Apply compression if instructed
byte[] plainText = bytes;
if (jweHeader.getCompressionAlgorithm().equals("DEF")) {
try {
plainText = DeflateUtils.compress(bytes);
} catch (Exception e) {
throw new RuntimeException("Failed to compress plainText");
}
}
// Compose the AAD
byte[] aad = Base64Util.b64Encode(jweHeader.toString()).getBytes(Charset.forName("UTF-8"));
// Encrypt the plain text according to the JWE enc
byte[] iv;
AuthenticatedCipherText authCipherText;
if (enc.equals(ENC_A128CBC_HS256) ||
enc.equals(ENC_A192CBC_HS384) ||
enc.equals(ENC_A256CBC_HS512)) {
iv = AESCBC.generateIV(randomGen);
authCipherText = AESCBC.encryptAuthenticated(cek, iv, plainText, aad);
} else if (enc.equals(ENC_A128GCM) ||
enc.equals(ENC_A192GCM) ||
enc.equals(ENC_A256GCM)) {
iv = AESGCM.generateIV(randomGen);
authCipherText = AESGCM.encrypt(cek, iv, plainText, aad);
} else {
throw new RuntimeException("Unsupported encryption method, must be A128CBC_HS256, A192CBC_HS384, A256CBC_HS512, A128GCM, A192GCM or A256GCM");
}
String serializedJWE = Base64Util.b64Encode(jweHeader.toString()) + "." +
Base64Util.b64Encode(encryptedKey) + "." +
Base64Util.b64Encode(iv) + "." +
Base64Util.b64Encode(authCipherText.getCipherText()) + "." +
Base64Util.b64Encode(authCipherText.getAuthenticationTag());
return serializedJWE;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy