JsonEncrypt.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */


  20. package org.openspcoop2.utils.security;

  21. import java.util.Iterator;
  22. import java.util.Properties;

  23. import org.apache.cxf.rs.security.jose.common.JoseConstants;
  24. import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
  25. import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
  26. import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
  27. import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
  28. import org.apache.cxf.rs.security.jose.jwe.JweJsonProducer;
  29. import org.apache.cxf.rs.security.jose.jwe.JweUtils;
  30. import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
  31. import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
  32. import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
  33. import org.openspcoop2.utils.UtilsException;
  34. import org.openspcoop2.utils.certificate.KeyStore;

  35. /**
  36.  * Encrypt
  37.  *
  38.  * @author Poli Andrea (apoli@link.it)
  39.  * @author $Author$
  40.  * @version $Rev$, $Date$
  41.  */
  42. public class JsonEncrypt {

  43.     private JweEncryptionProvider provider;
  44.    
  45.     private ContentAlgorithm contentAlgorithm;
  46.     private KeyAlgorithm keyAlgorithm;
  47.    
  48.     private JWEOptions options;
  49.    
  50.     private JweHeaders headers;
  51.     private JwtHeaders jwtHeaders;
  52.    
  53.     public JsonEncrypt(Properties props, JWEOptions options) throws UtilsException{
  54.         this(props, null, options);
  55.     }
  56.     public JsonEncrypt(Properties props, JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  57.         try {
  58.             this.headers = new JweHeaders();
  59.            
  60.             this.options=options;
  61.             String tmp = props.getProperty(JoseConstants.RSSEC_ENCRYPTION_ZIP_ALGORITHM);
  62.             if(tmp!=null && JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM.equalsIgnoreCase(tmp.trim())) {
  63.                 this.options.setDeflate(true); // overwrite options
  64.             }
  65.            
  66.             this.provider = JsonUtils.getJweEncryptionProvider(props);
  67.             if(this.provider==null) {
  68.                
  69.                 KeyAlgorithm keyAlgorithmP = JweUtils.getKeyEncryptionAlgorithm(props, null);
  70.                 if (KeyAlgorithm.DIRECT.equals(keyAlgorithmP)) {
  71.                     this.provider = JsonUtils.getJweEncryptionProviderFromJWKSymmetric(props, this.headers);
  72.                 }
  73.                 else {
  74.                     this.provider = JweUtils.loadEncryptionProvider(props, JsonUtils.newMessage(), this.headers);
  75.                 }
  76.             }
  77.            
  78.             this.contentAlgorithm = JweUtils.getContentEncryptionAlgorithm(props, ContentAlgorithm.A256GCM);
  79.             this.keyAlgorithm = JweUtils.getKeyEncryptionAlgorithm(props, null);
  80. /**         if(this.keyAlgorithm==null) {
  81. //              throw new Exception("KeyAlgorithm undefined");
  82. //          }*/
  83.                        
  84.             this.jwtHeaders = jwtHeaders;
  85.            
  86.         }catch(Exception t) {
  87.             throw JsonUtils.convert(options.getSerialization(), JsonUtils.ENCRYPT,JsonUtils.SENDER,t);
  88.         }
  89.     }
  90.    
  91.     public JsonEncrypt(java.security.KeyStore keystore, String alias, String keyAlgorithm, String contentAlgorithm,
  92.             JWEOptions options) throws UtilsException{
  93.         initTrustStore(new KeyStore(keystore), alias, keyAlgorithm, contentAlgorithm, null, options);
  94.     }
  95.     public JsonEncrypt(KeyStore keystore, String alias, String keyAlgorithm, String contentAlgorithm,
  96.             JWEOptions options) throws UtilsException{
  97.         initTrustStore(keystore, alias, keyAlgorithm, contentAlgorithm, null, options);
  98.     }
  99.     public JsonEncrypt(java.security.KeyStore keystore, String alias, String keyAlgorithm, String contentAlgorithm,
  100.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  101.         initTrustStore(new KeyStore(keystore), alias, keyAlgorithm, contentAlgorithm, jwtHeaders, options);
  102.     }
  103.     public JsonEncrypt(KeyStore keystore, String alias, String keyAlgorithm, String contentAlgorithm,
  104.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  105.         initTrustStore(keystore, alias, keyAlgorithm, contentAlgorithm, jwtHeaders, options);
  106.     }
  107.     private void initTrustStore(KeyStore keystore, String alias, String keyAlgorithm, String contentAlgorithm,
  108.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  109.         try {
  110.             this.options=options;
  111.            
  112.             this.keyAlgorithm  = org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm.getAlgorithm(keyAlgorithm);
  113.             this.contentAlgorithm = org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm.getAlgorithm(contentAlgorithm);
  114.             String compression = null;
  115.             if(this.options.isDeflate()) {
  116.                 compression = JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM;
  117.             }
  118.            
  119.             this.provider = JweUtils.createJweEncryptionProvider( keystore.getPublicKey(alias), this.keyAlgorithm, this.contentAlgorithm, compression);
  120.            
  121.             this.jwtHeaders = jwtHeaders;
  122.         }catch(Exception t) {
  123.             throw JsonUtils.convert(options.getSerialization(), JsonUtils.ENCRYPT,JsonUtils.SENDER,t);
  124.         }
  125.     }
  126.    
  127.     public JsonEncrypt(java.security.KeyStore keystore, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm,
  128.             JWEOptions options) throws UtilsException{
  129.         initKeystore(new KeyStore(keystore), alias, passwordPrivateKey, keyAlgorithm, contentAlgorithm, null, options);
  130.     }
  131.     public JsonEncrypt(KeyStore keystore, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm,
  132.             JWEOptions options) throws UtilsException{
  133.         initKeystore(keystore, alias, passwordPrivateKey, keyAlgorithm, contentAlgorithm, null, options);  
  134.     }
  135.     public JsonEncrypt(java.security.KeyStore keystore, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm,
  136.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  137.         initKeystore(new KeyStore(keystore), alias, passwordPrivateKey, keyAlgorithm, contentAlgorithm, jwtHeaders, options);
  138.     }
  139.     public JsonEncrypt(KeyStore keystore, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm,
  140.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  141.         initKeystore(keystore, alias, passwordPrivateKey, keyAlgorithm, contentAlgorithm, jwtHeaders, options);
  142.     }
  143.     private void initKeystore(KeyStore keystore, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm,
  144.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  145.         try {
  146.             this.options=options;
  147.            
  148.             this.keyAlgorithm  = org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm.getAlgorithm(keyAlgorithm);
  149.             this.contentAlgorithm = org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm.getAlgorithm(contentAlgorithm);
  150.             String compression = null;
  151.             if(this.options.isDeflate()) {
  152.                 compression = JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM;
  153.             }
  154.            
  155.             if (KeyAlgorithm.DIRECT.equals(this.keyAlgorithm)) {
  156.                 this.provider = JweUtils.getDirectKeyJweEncryption(keystore.getSecretKey(alias, passwordPrivateKey), this.contentAlgorithm);
  157.             }
  158.             else {
  159.                 this.provider = JweUtils.createJweEncryptionProvider(keystore.getSecretKey(alias, passwordPrivateKey), this.keyAlgorithm, this.contentAlgorithm, compression);
  160.             }
  161.            
  162.             this.jwtHeaders = jwtHeaders;
  163.         }catch(Exception t) {
  164.             throw JsonUtils.convert(options.getSerialization(), JsonUtils.ENCRYPT,JsonUtils.SENDER,t);
  165.         }
  166.     }

  167.     public JsonEncrypt(JsonWebKeys jsonWebKeys, boolean secretKey, String alias, String keyAlgorithm, String contentAlgorithm,
  168.             JWEOptions options) throws UtilsException{
  169.         initJsonWebKey(JsonUtils.readKey(jsonWebKeys, alias),secretKey, keyAlgorithm, contentAlgorithm, null, options);
  170.     }
  171.     public JsonEncrypt(JsonWebKeys jsonWebKeys, boolean secretKey, String alias, String keyAlgorithm, String contentAlgorithm,
  172.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  173.         initJsonWebKey(JsonUtils.readKey(jsonWebKeys, alias),secretKey, keyAlgorithm, contentAlgorithm, jwtHeaders, options);  
  174.     }
  175.     public JsonEncrypt(JsonWebKey jsonWebKey, boolean secretKey, String keyAlgorithm, String contentAlgorithm,
  176.             JWEOptions options) throws UtilsException{
  177.         initJsonWebKey(jsonWebKey,secretKey, keyAlgorithm, contentAlgorithm, null, options);    
  178.     }
  179.     public JsonEncrypt(JsonWebKey jsonWebKey, boolean secretKey, String keyAlgorithm, String contentAlgorithm,
  180.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  181.         initJsonWebKey(jsonWebKey,secretKey, keyAlgorithm, contentAlgorithm, jwtHeaders, options);  
  182.     }
  183.     private void initJsonWebKey(JsonWebKey jsonWebKey, boolean secretKey, String keyAlgorithm, String contentAlgorithm,
  184.             JwtHeaders jwtHeaders, JWEOptions options) throws UtilsException{
  185.         try {
  186.             this.options=options;
  187.            
  188.             this.keyAlgorithm  = org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm.getAlgorithm(keyAlgorithm);
  189.             this.contentAlgorithm = org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm.getAlgorithm(contentAlgorithm);
  190.             String compression = null;
  191.             if(this.options.isDeflate()) {
  192.                 compression = JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM;
  193.             }
  194.            
  195.             if(secretKey) {
  196.                 if(jsonWebKey.getAlgorithm()==null) {
  197.                     jsonWebKey.setAlgorithm(contentAlgorithm);
  198.                 }
  199.                 if (KeyAlgorithm.DIRECT.equals(this.keyAlgorithm)) {
  200.                     this.provider = JweUtils.getDirectKeyJweEncryption(JwkUtils.toSecretKey(jsonWebKey), this.contentAlgorithm);
  201.                 }
  202.                 else {
  203.                     this.provider = JweUtils.createJweEncryptionProvider(JwkUtils.toSecretKey(jsonWebKey), this.keyAlgorithm, this.contentAlgorithm, compression);
  204.                 }
  205.                 if(this.provider==null) {
  206.                     throw new UtilsException("(JsonWebKey) JwsEncryptionProvider init failed; check content algorithm ("+contentAlgorithm+")");
  207.                 }
  208.             }else {
  209.                 this.provider = JweUtils.createJweEncryptionProvider(JwkUtils.toRSAPublicKey(jsonWebKey), this.keyAlgorithm, this.contentAlgorithm, compression);
  210.             }
  211.            
  212.             this.jwtHeaders = jwtHeaders;
  213.         }catch(Exception t) {
  214.             throw JsonUtils.convert(options.getSerialization(), JsonUtils.ENCRYPT,JsonUtils.SENDER,t);
  215.         }
  216.     }
  217.    
  218.     public String encrypt(String jsonString) throws UtilsException{
  219.         try {
  220.             switch(this.options.getSerialization()) {
  221.                 case JSON: return encryptJson(jsonString);
  222.                 case COMPACT: return encryptCompact(jsonString);
  223.                 default: throw new UtilsException("Unsupported serialization '"+this.options.getSerialization()+"'");
  224.             }
  225.         }
  226.         catch(Exception t) {
  227.             throw JsonUtils.convert(this.options.getSerialization(), JsonUtils.ENCRYPT,JsonUtils.SENDER,t);
  228.         }
  229.     }
  230.     public String encrypt(byte[] json) throws UtilsException{
  231.         try {
  232.             switch(this.options.getSerialization()) {
  233.                 case JSON: return encryptJson(json);
  234.                 case COMPACT: return encryptCompact(json);
  235.                 default: throw new UtilsException("Unsupported serialization '"+this.options.getSerialization()+"'");
  236.             }
  237.         }
  238.         catch(Exception t) {
  239.             throw JsonUtils.convert(this.options.getSerialization(), JsonUtils.ENCRYPT,JsonUtils.SENDER,t);
  240.         }
  241.     }

  242.     private String encryptCompact(String jsonString) throws Exception {
  243.         return encryptCompact(jsonString.getBytes());
  244.     }
  245.     private String encryptCompact(byte[] json) throws Exception {  
  246.         JweHeaders headersBuild = null;
  247.         if(this.keyAlgorithm!=null) {
  248.             headersBuild = new JweHeaders(this.keyAlgorithm,this.contentAlgorithm,this.options.isDeflate());
  249.         }
  250.         else {
  251.             headersBuild = new JweHeaders(this.contentAlgorithm,this.options.isDeflate());
  252.         }
  253.         fillJwtHeaders(headersBuild, this.keyAlgorithm);
  254.         return this.provider.encrypt(json, headersBuild);
  255.     }


  256.     private String encryptJson(String jsonString) throws Exception {
  257.         return encryptJson(jsonString.getBytes());
  258.     }
  259.     private String encryptJson(byte[] json) throws Exception {
  260.        
  261.         JweHeaders sharedUnprotectedHeaders = null;
  262.         if(this.keyAlgorithm!=null) {
  263.             sharedUnprotectedHeaders = new JweHeaders();
  264.             sharedUnprotectedHeaders.setKeyEncryptionAlgorithm(this.keyAlgorithm);
  265.         }

  266.         JweHeaders protectedHeaders = new JweHeaders(this.contentAlgorithm, this.options.isDeflate());
  267.         fillJwtHeaders(protectedHeaders, this.keyAlgorithm);
  268.        
  269.         JweJsonProducer producer = null;
  270.         if(sharedUnprotectedHeaders!=null) {
  271.             protectedHeaders.removeProperty("alg"); // e' in sharedUnprotectedHeaders
  272.             producer = new JweJsonProducer(protectedHeaders, sharedUnprotectedHeaders, json);
  273.         }
  274.         else {
  275.             producer = new JweJsonProducer(protectedHeaders, json);
  276.         }
  277.        
  278.         return producer.encryptWith(this.provider);
  279.     }
  280.    
  281.     private void fillJwtHeaders(JweHeaders headers, org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm keyAlgo) throws Exception {
  282.         if(this.headers!=null &&
  283.             this.headers.asMap()!=null && !this.headers.asMap().isEmpty()) {
  284.             Iterator<String> itKeys = this.headers.asMap().keySet().iterator();
  285.             while (itKeys.hasNext()) {
  286.                 String key = itKeys.next();
  287.                 if(!headers.containsHeader(key)) {
  288.                     headers.setHeader(key, this.headers.getHeader(key));
  289.                 }
  290.             }
  291.         }
  292.         if(this.jwtHeaders!=null) {
  293.             this.jwtHeaders.fillJwsHeaders(headers, false, keyAlgo!=null ? keyAlgo.getJwaName() : null);
  294.         }
  295.     }

  296. }