{"id":20020659,"url":"https://github.com/netcentric/aem-crypto-support","last_synced_at":"2026-05-13T00:03:25.096Z","repository":{"id":258980299,"uuid":"864143716","full_name":"Netcentric/aem-crypto-support","owner":"Netcentric","description":"Wrapper around AEM's Crypto Support with FileVault Filtering Extension","archived":false,"fork":false,"pushed_at":"2024-10-21T09:38:51.000Z","size":111,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-02T03:34:48.285Z","etag":null,"topics":["aem","filevault","jackrabbit"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Netcentric.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-27T15:16:19.000Z","updated_at":"2024-12-09T19:54:57.000Z","dependencies_parsed_at":"2024-10-21T13:48:29.785Z","dependency_job_id":"6ba4fe0e-00d1-47cf-b197-c759c663c55d","html_url":"https://github.com/Netcentric/aem-crypto-support","commit_stats":null,"previous_names":["netcentric/aem-crypto-support"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Netcentric/aem-crypto-support","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcentric%2Faem-crypto-support","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcentric%2Faem-crypto-support/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcentric%2Faem-crypto-support/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcentric%2Faem-crypto-support/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Netcentric","download_url":"https://codeload.github.com/Netcentric/aem-crypto-support/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcentric%2Faem-crypto-support/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286079811,"owners_count":27282121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-26T02:00:06.075Z","response_time":193,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aem","filevault","jackrabbit"],"created_at":"2024-11-13T08:33:32.028Z","updated_at":"2025-11-27T01:06:57.932Z","avatar_url":"https://github.com/Netcentric.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AEM Crypto Support Library\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/Netcentric/aem-crypto-support/maven.yml?branch=main)](https://github.com/Netcentric/aem-crypto-support/actions)\n[![License](https://img.shields.io/badge/License-EPL%201.0-red.svg)](https://opensource.org/licenses/EPL-1.0)\n[![Maven Central](https://img.shields.io/maven-central/v/biz.netcentric.aem/aem-crypto-support)](https://search.maven.org/artifact/biz.netcentric.aem/aem-crypto-support)\n[![SonarCloud Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Netcentric_aem-crypto-support\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Netcentric_aem-crypto-support)\n[![SonarCloud Coverage](https://sonarcloud.io/api/project_badges/measure?project=Netcentric_aem-crypto-support\u0026metric=coverage)](https://sonarcloud.io/summary/new_code?id=Netcentric_aem-crypto-support)\n\n## Overview\n\nThis wrapper library allows to encrypt/decrypt with [AEM's CryptoSupport][aem-cryptosupport] outside AEM. The library provided by Adobe\nonly works inside AEM/OSGi runtimes. This wrapper adds some class loader tweaks and provides a simple API for constructing `CryptoSupport` objects. \nIn addition it provides an extension for [filtering in filevault-package-maven-plugin][filevault-filtering] to easily create encrypted values during the Maven build of content packages.\n\nThe encryption algorithm used internally is symmetrical **AES encryption (AES/CBC/PKCS5Padding)** with a **128 bit** key. Since it uses [Cypher Block Chaining](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) a random initialisation vector is used to make the encrypted text always look different (for the same plaintext). It uses [BSAFE Crypto-J from RSA (now Dell)][bsafe-wikipedia] as implementation basis.\n\n## Usage\n\nThis library can be used as extension for the filevault-package-maven plugin or programmatically via API.\n\n### Extension for filevault-package-maven-plugin\n\nThis library can be used with [`filevault-package-maven-plugin`][filevault-package-maven-plugin] in version 1.4.0 or newer to allow [resource filtering][filevault-filtering] with encryption support. This is useful to create encrypted values in content packages.\n\nThe master key (base-64 encoded) is looked up from either a Maven property with name `AEM_KEY` (or a same named environment variable) or `AEM_KEY_\u003cSUFFIX\u003e` in case a specific master key is referenced.\n\n#### Configuration of filevault-package-maven-plugin\n\n```\n\u003cplugin\u003e\n  \u003cgroupId\u003e\u003c/groupId\u003e\n  \u003cartifactId\u003e\u003c/artifactId\u003e\n  \u003cversion\u003e1.4.0\u003c/version\u003e \u003c!-- this is the minimum version required --\u003e\n  \u003cdependencies\u003e\n    \u003cdependency\u003e\n      \u003cgroupId\u003ebiz.netcentric.aem\u003c/groupId\u003e\n      \u003cartifactId\u003eaem-crypto-support\u003c/artifactId\u003e\n      \u003cversion\u003e1.0.0\u003c/version\u003e\n    \u003c/dependency\u003e\n  \u003c/dependencies\u003e\n  \u003cconfiguration\u003e\n    \u003cenableJcrRootFiltering\u003etrue\u003c/enableJcrRootFiltering\u003e\u003c!-- enable filtering --\u003e\n  \u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n\n#### Usage in FileVault DocView files\n\n```\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cjcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\"\n  jcr:primaryType=\"nt:unstructured\"\n  ...\n  encryptedValue=\"${vltattributeescape.vltaemencrypt.env.MY_SECRET}\" /\u003e\n```\n\nThis will encrypt the value provided through the environment variable `MY_SECRET` and afterwards [escape the encrypted value according to FileVault DocView rules][filevault-escape].\n\nIn order to use specific keys (e.g. when targeting multiple environments with different master keys in the same build) use a suffix after `vltaemencrypt` like `vltaemencryptprod.env.MY_SECRET`.\nThis will encrypt `MY_SECRET` with the master key provided in Maven property with name `AEM_KEY_PROD` or a same named environment variable (in that order). Note that the *suffix* (`prod` in this case) is automatically converted to uppercase letters before being used in the environment variable/property name.\n\n### API \n\n```\ntry (CryptoSupportFactory cryptoSupportFactory = new CryptoSupportFactory(this.getClass().getClassLoader())) {\n    CryptoSupport cryptoSupport = cryptoSupportFactory.create(\"your base64 encoded key);\n    cryptoSupport.protect(\"my secret value\");\n    cryptoSupport.unprotect(\"my encrypted value\");\n}\n```\n\n## Retrieve key from AEM environment\n\nThe easiest way to retrieve the (usually auto-generated random) master key from an AEM server is to leverage the [Groovy Console][groovyconsole]. The key is usually stored on the file system (either below the bundle data directory or in a directory given through OSGi property/environment variable with name `com.adobe.granite.crypto.keys.path`). It can be exposed with the following Groovy script.\n\n```\norg.osgi.framework.Bundle bundle = Arrays.asList(bundleContext.getBundles()).find { \"com.adobe.granite.crypto.file\".equals(it.getSymbolicName()) };\n\nout.println(\"Bundle \" + bundle);\nout.println(\"Data File \" + bundle.getBundleContext().getDataFile(\"master\"));\nString keyPath = bundle.getBundleContext().getProperty(\"com.adobe.granite.crypto.keys.path\");\nout.println(\"Keys Path \" + keyPath );\nFile masterFile;\nif (keyPath != null) {\n    masterFile = new File(keyPath, \"master\");\n} else {\n    masterFile = bundle.getDataFile(\"master\")\n}\nbyte [] bytes = java.nio.file.Files.readAllBytes(masterFile.toPath());\nout.println(\"master key in base64 encoding:\\n\" + Base64.getEncoder().encodeToString(bytes));\n```\n\n## Use Cases\n\nSeveral [AEM Cloud Service configurations][aem-cloudservice-configs] still access (encrypted) credentials from the repository (like [Dynamic Media configuration][dynamic-media-aem-config]) instead of leveraging interpolated OSGi configurations.\nThose can be automatically configured via content packages with the help of this FileVault extension.\n\n## Best Practices\n\n* Never store either master keys or to be encrypted values (in clear text) in any source code management system like Git. They should always be injected via some secure means as environment variables:\n    * For CloudManager this is [secret pipeline variables][cloudmanager-pipelinevars], \n    * for GitHub Actions this is [secrets][gha-secrets],\n    * Jenkins has a dedicated [Credentials API Plugin][jenkins-credentials-plugin].\n\n* Preferably use secret values in OSGi configuration which have [native support for interpolation with secrets in AEMaaCS](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/deploying/configuring-osgi#when-to-use-secret-environment-specific-configuration-values) instead of encrypting and storing sensitive values within the repository.\n\n* Don't overwrite/modify the default IMS configurations provided for integrations with other Adobe tools (like Adobe Analytics, Asset Compute, or Adobe Tags fka Adobe DTM).\n\n## Limitations\n\nAEMaaCS doesn't support [different mutable content packages for different environments](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/deploying/overview#mutable-content-packages). Although it is possible to use [CloudManager pipeline variables][cloudmanager-pipelinevars] to cater for differences in the master key between DEV and STAGE, this approach does not work for STAGE and PROD (because those share a common build artifact/pipeline).\n\nThe only way to automate the deployment is individually modifying the encrypted properties via [Repoinit](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/deploying/overview#repoinit) with an OSGi configuration leveraging [secret environment-specific variables](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/deploying/configuring-osgi#when-to-use-secret-environment-specific-configuration-values), i.e. the same repoinit script can be used on all environments, as long as the actual secret value is set differently for those environments (with the relevant **encrypted** values).\nAs dealing with repoinit is cumbersome, one should only adjust the relevant properties with it and leverage a common content package for the other common properties/child nodes.\nJust make sure to exclude the [environment-specific property in the filter rules](https://jackrabbit.apache.org/filevault/filter.html#Property_Filtering) because the order of installation is\n1. Repoinit\n2. Mutable Content Package Installation\n\nIf someone comes up with either\n1. an enhanced [OSGi Configuration Plugin for interpolation with encryption](https://github.com/apache/felix-dev/blob/master/configadmin-plugins/interpolation/src/main/java/org/apache/felix/configadmin/plugin/interpolation/InterpolationConfigurationPlugin.java) or\n2. a [Repoinit extension](https://sling.apache.org/documentation/bundles/repository-initialization.html) to encrypt values\nplease let me know.\n\n## Alternative Approach\n\n[CONGA](https://devops.wcm.io/conga/plugins/aem/handlebars-helpers.html) has support for encrypting values in handlebar templates. However, CONGA uses the default [SunJCE implementation](https://docs.oracle.com/en/java/javase/11/security/oracle-providers.html#GUID-A47B1249-593C-4C38-A0D0-68FA7681E0A7) for performing the `AES/CBC/PKCS5Padding` encryption instead of using the JSafe implementation used in AEM.\n\nAdobe, and AEM are either registered trademarks or trademarks of Adobe in\nthe United States and/or other countries.\n\n[bsafe-wikipedia]: https://en.wikipedia.org/wiki/BSAFE\n[aem-cryptosupport]: https://developer.adobe.com/experience-manager/reference-materials/6-5/javadoc/com/adobe/granite/crypto/CryptoSupport.html\n[groovyconsole]: https://github.com/orbinson/aem-groovy-console\n[filevault-package-maven-plugin]: https://jackrabbit.apache.org/filevault-package-maven-plugin/index.html\n[filevault-filtering]: https://jackrabbit.apache.org/filevault-package-maven-plugin/filtering.html#Filtering_Extensions\n[filevault-escape]: https://jackrabbit.apache.org/filevault/docview.html#Escaping]\n[cloudmanager-pipelinevars]: https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/using-cloud-manager/cicd-pipelines/pipeline-variables\n[gha-secrets]: https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions\n[jenkins-credentials-plugin]: https://github.com/jenkinsci/credentials-plugin/tree/master/docs\n[dynamic-media-aem-config]: https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/assets/dynamicmedia/config-dm#configuring-dynamic-media-cloud-services\n[aem-cloudservice-configs]: https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/extending-aem/extending-cloud-services/extending-cloud-config\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetcentric%2Faem-crypto-support","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetcentric%2Faem-crypto-support","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetcentric%2Faem-crypto-support/lists"}