Introduction
Jobs might require variables for parameterization that hold secrets. We find a number of requirements for management of such variables, see JS7 - How to encrypt and decrypt Variables
The preferred solution with JS7 is to use asymmetric keys:
- Encryption and decryption can be performed directly by related jobs or outside of JS7 products.
- This includes that JS7 products have no knowledge of secrets involved that potentially could be compromised by logging, database persistence etc.
FEATURE AVAILABILITY STARTING FROM RELEASE 2.5.9
FEATURE AVAILABILITY STARTING FROM RELEASE 2.6.6
Download
The solution ships with JS7 Agents that can use encyption/decryption from shell jobs.
In addition, the solution is provided for download to perform encryption and decryption outside of JS7 products.
- Download: JS7 - Download
- The solution is available for Linux, MacOS®, AIX® using bash, zsh, dash shell, see JS7 - How to encrypt and decrypt using Unix Shell. Encryption and decryption with Unix and Windows can be used interchangeably.
- The solution is available for Windows® Shell.
Managing the Private Key and Certificate
Assymetric encryption makes use of a Private Key and Certificate/Public Key that can be created in a number of ways:
- Users can create a Certificate Signing Request (CSR) and ask their Certificate Authority (CA) to sign the CSR and to receive an X.509 certificate. The X.509 Private Key or Certificate allow to derive the Public Key.
- User can create a self-signed X.509 Certificate, see JS7 - How to create self-signed Certificates.
- Users can create a Private Key and Certificate as explained in the next chapter.
Step 1: Creating the Private Key and Certificate
The following step is performed on the server hosting the Agent that should decrypt secrets. The example makes use of the openssl
command line utility that can be installed for Windows. There are alternative ways how to create Private Keys and Certificates.
# navigate to the Agent's <agent-data>/config/private directory cd /var/sos-berlin.com/js7/agent/config/private # create the private key in pkcs#1 format # without passphrase # openssl ecparam -name secp256k1 -genkey -noout -out agent.key # with passphrase openssl ecparam -genkey -name secp256k1 | openssl ec -aes256 -passout pass:"jobscheduler" -out agent.key # create certificate openssl req -new -x509 -key agent.key -passin pass:"jobscheduler" -out agent.crt -days 1825 # extract public key from private key (not required) # openssl ec -in agent.key -passin pass:"jobscheduler" -pubout > agent.pub
# navigate to the Agent's <agent-data>/config/private directory cd /var/sos-berlin.com/js7/agent/config/private # create the private key in pkcs#1 format # without passphrase # openssl req -x509 -sha256 -newkey rsa:2048 -keyout agent.key -out agent.crt # with passphrase openssl req -x509 -sha256 -newkey rsa:2048 -passout pass:"jobscheduler" -keyout agent.key -out agent.crt # extract public key from certificate (not required) # openssl x509 -pubkey -noout -in agent.crt > agent.pub
Step 2: Making the Certificate available
Copy the Certificate file to the server(s) hosting the Agent(s) that should encrypt variables:
# navigate to the Agent's <agent-data>/config directory Set-Location $env:ProgramData/sos-berlin.com/js7/agent/config # cd %ProgramData%/sos-berlin.com/js7/agent/config # copy the agent.crt certificate file from to the current location using a file transfer tool or your clipboard
Encryption
Usage
Invoking the script without arguments displays the usage clause:
Usage: js7_encrypt.cmd [Options] [Switches] Options: --cert=<path-to-certificate> | path to X.509 certificate or public key file used to encrypt the secret. --in=<secret> | secret that should be encrypted. --infile=<path-to-file> | path to input file. --outfile=<path-to-file> | path to output file that should be encrypted. Switches: -h | --help | displays usage
Options
--cert
- Specifies the path to a file that holds the CA signed or self-signed X.509 Certificate. Alternatively the path to a file holding the Public Key can be specified.
--in
- Specifies the input value that should be encrypted, typically a secret.
- One of the options
--in
or--infile
has to be specified.
--infile
- Specifies the path to the input file that should be encrypted.
- One of the options
--in
or--infile
has to be specified. - This option requires use of the
--outfile
option.
--outfile
- Specifies the path to the output file that will be created holding the encrypted content of the input file.
- The option is required if the
--infile
option is specified.
Switches
-h | --help
- Displays usage.
Exit Codes
1
: argument errors2
: processing errors
Return Values
The script writes output to the JS7_ENCRYPT_VALUE
environment variable. Output includes the following items separated by spaces:
- encrypted symmetric key,
- base64 encoded initialization vector,
- encrypted secret.
Examples
The following examples illustrate typical use cases.
Encrypting Secret using Windows Shell
call .\bin\js7_encrypt.cmd "--cert=agent.crt" "--in=secret" @echo %JS7_ENCRYPT_VALUE% @rem encrypts the given secret using an Agent's X.509 certificate @rem consider that for Windows Shell all arguments have to be quoted @rem output is provided from an environment variable that includes the symmetric key, initialization vector and encrypted string separated by space
Encrypting and forwarding Secret using Windows Shell in Jobs
call .\bin\js7_encrypt.cmd "--cert=agent.crt" "--in=secret" @echo result=%JS7_ENCRYPT_VALUE% >> %JS7_RETURN_VALUES @rem encrypts the given secret using an Agent's X.509 certificate @rem consider that for Windows Shell all arguments have to be quoted @rem output is stored to the "result" variable (key/value pair) that is made available for later jobs in the workflow
Encrypting File using Windows Shell
echo secret file > %TEMP%\secret.txt call .\bin\js7_encrypt.cmd "--cert=agent.crt" "--infile=%TEMP%\secret.txt" "--outfile=%TEMP%\secret.txt.encrypted" @echo %JS7_ENCRYPT_VALUE% @rem encrypts the given file using an Agent's X.509 certificate @rem consider that for Windows Shell all arguments have to be quoted @rem output is available from the JS7_ENCRYPT_VALUE environment variable @rem output includes the symmetric key, initialization vector and encrypted file separated by space
Decryption
Usage
Invoking the script without arguments displays the usage clause:
Usage: js7_decrypt.cmd [Options] [Switches] Options: --key=<path> | path to private key file for decryption. --key-password=<password> | password for the private key. --iv=<initialization-vector> | base64 encoded initialization vector (returned by encryption). --encrypted-key=<key> | base64 encoded encrypted symmetric key (returned by encryption). --in=<encrypted-secret> | encrypted secret to decrypt (returned by encryption). --infile=<path-to-file> | path to encrypted input file. --outfile=<path-to-file> | path to decrypted output file. Switches: -h | --help | displays usage
Options
--key
- Specifies the path to a the Private Key file that matches the X.509 Certificate or Public Key used for previous encryption.
- The argument is required.
--key-password
- Specifies the password if the Private Key file indicated with the
--key
option is protected by a password.
- Specifies the password if the Private Key file indicated with the
--iv
- Specifies the base64 encoded initialization vector as returned during encryption.
- The argument is required.
--encrypted-key
- Specifies the base64 encoded, encrypted symmetric key as returned during encryption.
- The argument is required.
--in
- Specifies the encrypted value that should be decrypted.
- One of the options
--in
or--infile
has to be specified.
--infile
- Specifies the path to an encrypted file that should be decrypted.
- One of the options
--in
or--infile
has to be specified. - This option requires use of the
--outfile
option.
--outfile
- Specifies the path to the output file that will be created holding the decrypted content of the input file.
- The option is required if the
--infile
option is specified.
Switches
-h | --help
- Displays usage.
Exit Codes
1
: argument errors2
: processing errors
Return Values
The script creates the following environment variables:
JS7_DECRYPT_VALUE
holds the decrypted secret if the--in
option is used,JS7_DECRYPT_FILE
holds the path to the decrypted output file if the--infile
and--outfile
options are used.
Examples
The following examples illustrate typical use cases.
Decrypting Secret using Windows Shell
@rem call .\bin\js7_encrypt.cmd "--cert=agent.crt" "--in=secret" for /f "tokens=1-3" %%i in ("%JS7_ENCRYPT_VALUE%") do ( set encrypted_symmetric_key=%%i set encrypted_base64_iv=%%j set encrypted_string=%%k ) call .\bin\js7_decrypt.cmd ^ "--key=agent.key" ^ "--key-password=jobscheduler" ^ "--encrypted-key=%encrypted_symmetric_key%" ^ "--iv=%encrypted_base64_iv%" ^ "--in=%encrypted_string%" @echo %JS7_DECRYPT_VALUE% @rem decrypts the encrypted secret using an Agent's private key and passphrase @rem consider that for Windows Shell all arguments have to be quoted @rem the JS7_DECRYPT_VALUE environment variable is automatically created and holds the decrypted secret
Decrypting File using Windows Shell
@rem call .\bin\js7_encrypt.cmd "--cert=agent.crt" "--infile=%TEMP%\secret.txt" "--outfile=%TEMP%\secret.txt.encrypted" for /f "tokens=1-3" %%i in ("%JS7_ENCRYPT_VALUE%") do ( set encrypted_symmetric_key=%%i set encrypted_base64_iv=%%j set encrypted_file=%%k ) call .\bin\js7_decrypt.cmd ^ "--key=agent.key" ^ "--key-password=jobscheduler" ^ "--encrypted-key=%encrypted_symmetric_key%" ^ "--iv=%encrypted_base64_iv%" ^ "--infile=%encrypted_file%" ^ "--outfile=%TEMP%\secret.txt.decrypted" type %TEMP%\secret.txt.decrypted @rem decrypts the given encrypted file using an Agent's private key and passphrase @rem the JS7_ENCRYPT_VALUE environment variable is returned in the encryption step and holds the encrypted symmetric key, initialization vector and path to the encrypted file @rem consider that for Windows Shell all arguments have to be quoted @rem output includes the path to the decrypted file that is provided from the JS7_DECRYPT_FILE environment variable