Chiffrement AWS

Version

Simplicité 5.1.33

Description

Bonjour,

Pouvons nous par nous même intégrer des librairies java tierces ou elle doivent êtres dans le socle applicatif ?
Dans notre cas, nous avons besoin d’utiliser le sdk AWS pour faire appel à des mécanismes de cryptage.

<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.17.136</version>
<optional>true</optional>
<type>pom</type>
<scope>import</scope>
</dependency>
 <dependency>
   <groupId>com.amazonaws</groupId>
   <artifactId>aws-encryption-sdk-java</artifactId>
   <version>2.3.3</version>
</dependency>
</dependencies>
</dependencyManagement>

Merci d’avance.

L’ajout de JARs n’est jamais “plug and play” car il peut potentiellement y avoir des conflits avec d’autres JARs déjà embarqués dans la plateforme, et donc avoir des effets de bord imprévisibles. C’est pour cela qu’on préfère regarder d’abord de quoi il retourne précisément.

En l’occurrence l’ajout de cette dépendance ne semble pas ajouter trop de choses ni induire de conflits, voilà l’écart vs les dépendances de la plateforme dans sa version de dev courante (5.3-alpha):

Cette lib pourrait donc être éligible à être intégrée à terme à la plateforme (car elle est sous licence Apache 2.0).

Je regarderai plus tard ce que ça donne sur la 5.2-beta et sur la 5.1 mais on évite des les intégrations de nouvelles libs ailleurs que sur la version de dev courante.

En tout état de cause, il existe 2 manières d’ajouter manuellement les libs:

  1. soit au niveau du paramétrage par ajout de “shared codes” de type “JAR” (c’est le plus souple quand il n’y a pas 50 dépendances indirectes)
  2. soit au niveau de l’image Docker en buildant une image enrichie à partir de la notre:
FROM simplicite:platform:<tag>
ADD --chown=simplicite:simplicite *.jar /usr/local/tomcat/webapps/ROOT/WEB-INF/lib

Attention de ne bien ajouter que les libs additionnelles et de proscrire absolument les JARs “bundle” qui embarquent plusieurs JAR fusionnés dans un seul JAR car il y a alors 99% de chances que ça embarque des classes en conflit.

Bon, en 5.1 ce sont aussi les même 2 libs qu’ajoute la dépendance

Analyse faite, on va les intégrer au socle, y compris en 5.1 pour vous simplifier les choses car :

  • on a déjà la lib bcprov, or si j’en crois bouncycastle.org la bcprov-ext contient tout ce qu’il y a dans bcprov plus un algo additionnel (NTRU). On va donc remplacer la bcprov par la bcprov-ext (en passant de 0.68 à 0.69)
  • il ne reste alors que la lib aws-encryption-sdk-java qui ne contient rien d’autre que des classes en com.amazonws.* donc ça ne peut pas poser de pb de l’ajouter

Ce sera fait dans le cadre de la prochaine révision 5.1.35 qui devrait arriver rapidement pour d’autres sujets.

En attendant (si vous n’utilisez pas l’algo NTRU)je pense vous pouvez juste ajouter manuellement le JAR aws-encryption-sdk-java-2.3.3.jar (cf. ma réponse précédente) ça devrait marcher avec la bcprov déjà présente mais il faudra de toute façon la supprimer quand vous upgraderez en 5.1.35.

La 5.1.35 avec la lib en question a été releasée le 19/03/22, quand vous upgraderez sur cette révision, n’oubliez pas de supprimer l’ajout spécifique de cette lib au risque de vous retrouver tôt ou tard avec des conflits de version car on maintiendra cette lib à jour.

Je teste aujourd’hui l’utilisation de KMS mais cela ne fonctionne pas à priori. Je n’ai pas essayé d’intégrer de lib à la main et je n’en ai pas la possibilité.

java.lang.NoClassDefFoundError: com/amazonaws/auth/AWSCredentialsProvider
at com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider.builder(KmsMasterKeyProvider.java:371)
at com.simplicite.commons.name.NamHealthcareDataTools.kmsEncrypt(NamHealthcareDataTools.java:73)
at com.simplicite.commons.name.NamHealthcareDataTools.encrypt(NamHealthcareDataTools.java:65)
at com.simplicite.objects.name.NamJeune.encryptHealthData(NamJeune.java:1175)
at com.simplicite.objects.name.NamJeune.preSave(NamJeune.java:810)
at com.simplicite.util.ObjectHooks.preSave(ObjectHooks.java:664)
at com.simplicite.util.engine.ObjectManager.save(ObjectManager.java:3327)
at com.simplicite.util.engine.ObjectDirect.save(ObjectDirect.java:478)
at com.simplicite.util.ObjectDB.save(ObjectDB.java:1315)
at com.simplicite.webapp.tools.JSONServletTool.update(JSONServletTool.java:1224)
at com.simplicite.webapp.ObjectJson.update(ObjectJson.java:343)
at com.simplicite.webapp.tools.JSONServletTool.businessObjectService(JSONServletTool.java:626)
at com.simplicite.webapp.servlets.AbstractJSONServlet.service(AbstractJSONServlet.java:89)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.simplicite.webapp.filters.HTTPHeadersFilter.doFilter(HTTPHeadersFilter.java:39)
at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.simplicite.webapp.filters.AuthMethodFilter.doFilter(AuthMethodFilter.java:174)
at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.simplicite.webapp.filters.RewriteFilter.doFilter(RewriteFilter.java:86)
at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:183)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at com.simplicite.tomcat.valves.APISessionValve.invoke(APISessionValve.java:231)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ClassNotFoundException: com.amazonaws.auth.AWSCredentialsProvider
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1407)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1215)
… 49 more

Le code en question

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.CryptoResult;
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;

[...]

 private static byte[] kmsEncrypt(byte[] plainValuestBytes) {
        AwsCrypto crypto = AwsCrypto.builder()
                .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
                .build();

       //L'exception est lancée ici
       KmsMasterKeyProvider keyProvider = KmsMasterKeyProvider.builder().buildStrict(KMS_KEY_ARN); 

        CryptoResult<byte[], KmsMasterKey> encryptResult = crypto.encryptData(keyProvider,
                plainValuestBytes, encryptionContext);
            return encryptResult.getResult();
    }

Quelle révision utilisez vous ?

Pardon, 5.1.36.

Merci d’avance.

En 5.1.35 nous avons intégré la lib aws-encryption-sdk-java dans sa dernière version de l’époque (2.3.3) : https://mvnrepository.com/artifact/com.amazonaws/aws-encryption-sdk-java/2.3.3

Nous n’avons pas intégré sa dépendance optionnelle aws-java-sdk : https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk/1.12.54 car celle-ci tire des centaines de libs AWS qui, de part leur volume et leur caractère propriétaire, n’ont pas vocation à faire partie de la plateforme Simplicité.

Votre classe manquante doit être dans une de ces libs.

Une bonne approche est donc d’identifier les libs nécessaires et suffisantes dans votre cas d’usage précis puis de les ajouter comme décrit plus haut:

  • soit en construisant une image Docker custom en partant de la notre,
  • soit, s’il n’y en a pas des dizaines/centaines, en les ajoutant en shared code de type JAR

Ici aussi indiquez nous la liste de ces libs pour qu’on s’assure qu’elles n’induisent pas de conflits, faute de quoi il peut y avoir de effets de bord imprévisibles.

Vous pouvez aussi raisonner différemment pour éviter tout conflit de dépendances :

  • ajouter à nos images une webapp indépendante de la webapp Simplicité en charge du cryptage/décryptage via appel de services ad hoc,
  • packager un JAR de type “module Java” qui isole les dépendances et expose des méthodes de cryptage/décryptage et l’ajouter dans l’image ou en shared code de type JAR
  • etc.

Cela dit, la classe helper EncryptionTool (cf. EncryptionTool) offre nativement des mécanismes de cryptage/décryptage certes plus simples mais qui évitent des travaux d’intégrateur plus complexes

Bonjour,

Merci, je vais intégrer la dépendance dans l’image docker donc.

Du coup je m’interroge sur l’intérêt de conserver la lib aws-encryption-sdk-java dans la plateforme sachant que celle-ci est un wrapper des libs Bouncy Castle et ne peut visiblement pas, dans la “vraie vie”, être utilisé sans tout sa grappe d’autres libs AWS “optionnelles”

Si vous n’y voyez pas d’inconvénient je propose de la retirer dans la prochaine révision.

Pour info, nous réfléchissons actuellement à un processus plus simple pour le check et l’ajout de dépendances complexes dans le cadre de build d’images customs car c’est clairement de ça qu’on parle dans ce contexte (la notion paramétrable de shared code de type JAR n’a de sens que pour les cas simples où on ne parle que d’un - ou de qques - JAR qu’on a checké préalablement vs le POM effectif de la plateforme qui, pour mémoire, disponible sur le /maven de l’instance, ce n’est pas un mécanisme adapté pour de l’ajout de dépendances). Cela reposera sans doute sur une image Docker plus riche/spécifique qui embarquera notamment Maven.

Effectivement la solution avec un docker qui embarque maven serait bien pratique.

Aussi, peut-on laisser la dépendance aws-encryption ? Le jar n’est pas en ligne contrairement à aws-sdk que j’ai pu ajouter directement a notre dockerfile.

Nous avons supprimé la lib car ça n’a pas de sens de conserver dans la plateforme une lib inutilisable sans le SDK complet. Celle -ci est tout autant disponible en ligne sur le registry Maven central que le SDK:

        <dependency>
          <groupId>com.amazonaws</groupId>
          <artifactId>aws-encryption-sdk-java</artifactId>
          <version>2.4.0</version>
        </dependency>

Et quelle est la procédure pour récupérer le jar depuis maven dans le dockerfile ? J’ai pas de lien aws pour telecharger le jar aws-encryption directement contrairement à la dépendance que je viens d’intégrer de cette manière.

D’autre par, aws-encryption peut fonctionner sans le SDK complet sauf pour la fonctionalité KMS (je cherche aussi la logique aussi d’avoir inégrer KMS là dedans si le SDK est nécessaire alors qu’elle nest pas en dépendance)

Tout JAR publié sur le registry Maven central est téléchargeable en ligne

ex: là


ou là

etc.
ou à la “source” ici:
image

Nous travaillons actuellement à la conception/implémentation de la procédure d’ajout de dépendances “assistée” par Maven dans le cadre de build d’une image custom. Ce sera documenté d’ici peu le temps de finaliser et de roder tout ça.

D’ici là la recopie de vos JAR additionnels peut se faire par des ADD explicites comme décrit plus haut.

Cf. Add custom Maven-asssited dependencies to your custom images - #2

Dans votre cas la commande sera à priori du type:

docker build \
  -f Dockerfile-add-custom-dependencies \
  -t simplicite/platform:5-latest-with-aws-sdk \
  --build-arg deps="com.amazonaws:aws-encryption-sdk-java:2.4.0 com.amazonaws:aws-java-sdk:1.12.193" .

bonjour et merci !
J’ai fait le modifications nécéssaires dans le dockerfile et dans la construction de l’image.
Une question
adddeps.sh est bien un script sur votre image ?

USER root
ARG maven=3.8.5
ARG deps
SHELL ["/bin/bash", “-o”, “pipefail”, “-c”]
RUN wget -qO- https://www-eu.apache.org/dist/maven/maven-3/$maven/binaries/apache-maven-$maven-bin.tar.gz | tar xfz - && *
** MAVEN_HOME=/usr/local/tomcat/apache-maven-$maven ./adddeps.sh $deps && *

** rm -fr /usr/local/apache-maven-$maven**
USER simplicite

Présicions:
J’ai du ajouter l’option pipefail au début pour respecter le lint.
J’ai mis le user root au début car il me mettait des permission denied sur des créations de repertoitre ?!
Et j’ai mis le user simplicite a la fin car hadolint bloque le build si on laisse root a la fin du dockerfile

Ce n’est applicable qu’aux dernières images (re)construites hier soir (sinon le script adddeps.sh n’est pas présent, c’est lui la nouveauté)

Et, non l’ordre des USER ne doit pas être inversé afin que l’ensemble des fichiers appartiennent bien in fine au user simplicite comme le reste.

J’ai testé la procédure indiquée dans votre cas et ça fonctionne:

> docker build \
>   -f Dockerfile-add-custom-dependencies \
>   -t simplicite/platform:5-latest-with-aws-sdk \
>   --build-arg deps="com.amazonaws:aws-encryption-sdk-java:2.4.0 com.amazonaws:aws-java-sdk:1.12.193" .
Sending build context to Docker daemon  6.006GB
Step 1/8 : ARG reg=registry.simplicite.io
Step 2/8 : ARG tag=5-latest
Step 3/8 : FROM $reg/platform:$tag
5-latest: Pulling from platform
Digest: sha256:cfb102591159044b65df931e30873493ec566ae8a2c051e30e15f6f735119109
Status: Downloaded newer image for registry.simplicite.io/platform:5-latest
 ---> 8e06eb37db85
Step 4/8 : USER simplicite
 ---> Running in a0404ad652b2
Removing intermediate container a0404ad652b2
 ---> 071f4860f302
Step 5/8 : ARG maven=3.8.5
 ---> Running in 92b8d7e3cba8
Removing intermediate container 92b8d7e3cba8
 ---> 5764ce88bae3
Step 6/8 : ARG deps
 ---> Running in 31a965528990
Removing intermediate container 31a965528990
 ---> 046cd3f54b42
Step 7/8 : RUN wget -qO- https://www-eu.apache.org/dist/maven/maven-3/$maven/binaries/apache-maven-$maven-bin.tar.gz | tar xfz - &&     MAVEN_HOME=/usr/local/tomcat/apache-maven-$maven ./adddeps.sh $deps &&     rm -fr /usr/local/apache-maven-$maven
 ---> Running in 5731ceffd7cb
Tomcat root: /usr/local/tomcat
Generating pom.xml...
Done
Resolution of dependencies...
Done
Copying dependencies...
- aws-encryption-sdk-java-2.4.0.jar copied
- aws-java-sdk-1.12.193.jar copied
- aws-java-sdk-accessanalyzer-1.12.193.jar copied
- aws-java-sdk-account-1.12.193.jar copied
(...)
Done
Removing intermediate container 5731ceffd7cb
 ---> 29d62b5bbb8c
Step 8/8 : USER root
 ---> Running in 00bcfcc289d9
Removing intermediate container 00bcfcc289d9
 ---> 8a99d557c5e9
Successfully built 8a99d557c5e9
Successfully tagged simplicite/platform:5-latest-with-aws-sdk

> docker images
REPOSITORY                        TAG                         IMAGE ID       CREATED         SIZE
simplicite/platform               5-latest-with-aws-sdk       8a99d557c5e9   8 seconds ago   1.64GB
simplicite/platform               5-alpha                     5afa2005ccff   8 hours ago     1.38GB

Je précise que c’est une procédure nouvelle qui sera sans doute enrichie/améliorée progressivement

D’ailleurs il y avait un petit bug dans le rm final => c’est corrigé et poussé sur Dockerfile-add-custom-dependencies

rm -fr /usr/local/apache-maven-$maven

changé en

rm -fr /usr/local/tomcat/apache-maven-$maven

Et l’expression régulière qui checke la présence de libs dans une version différente ne gérait pas tous les cas de nommages.

Dans votre cas particulier des libs netty-* dont le numéro de version a un format atypique passent dans les mailles du filet.

Ca a été corrigé et les images seront rebuildé dans la journée.

1 Like