This is an automated email from the ASF dual-hosted git repository. orpiske pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 13f9402cdd0ad59e63c4f2f0db13115756c3da07 Author: Otavio R. Piske <angusyo...@gmail.com> AuthorDate: Sat Feb 17 13:47:12 2024 +0100 CAMEL-20410: documentation fixes for camel-crypto - Fixed samples - Converted to use tabs - Fixed grammar and typos - Fixed punctuation - Added and/or fixed links Signed-off-by: Otavio R. Piske <angusyo...@gmail.com> --- .../src/main/docs/crypto-component.adoc | 24 ++++---- .../src/main/docs/crypto-dataformat.adoc | 66 ++++++++++++++-------- .../camel-crypto/src/main/docs/pgp-dataformat.adoc | 65 +++++++++++---------- 3 files changed, 92 insertions(+), 63 deletions(-) diff --git a/components/camel-crypto/src/main/docs/crypto-component.adoc b/components/camel-crypto/src/main/docs/crypto-component.adoc index f963d836b35..4837da3602f 100644 --- a/components/camel-crypto/src/main/docs/crypto-component.adoc +++ b/components/camel-crypto/src/main/docs/crypto-component.adoc @@ -14,8 +14,8 @@ *{component-header}* -With Camel cryptographic endpoints and Java's Cryptographic extension it -is easy to create Digital Signatures for Exchanges. +With Camel cryptographic endpoints and Java's Cryptographic extension, it +is possible to create Digital Signatures for Exchanges. Camel provides a pair of flexible endpoints which get used in concert to create a signature for an exchange in one part of the exchange's workflow and then verify the signature in a later part of the workflow. @@ -43,9 +43,9 @@ closely guarded and used to 'sign' the message while the other, public key, is shared around to anyone interested in verifying the signed messages. Messages are signed by using the private key to encrypting a digest of the message. This encrypted digest is transmitted along with -the message. On the other side the verifier recalculates the message +the message. On the other side, the verifier recalculates the message digest and uses the public key to decrypt the digest in the -signature. If both digests match the verifier knows only the holder of +signature. If both digests match, the verifier knows only the holder of the private key could have created the signature. Camel uses the Signature service from the Java Cryptographic Extension @@ -61,7 +61,7 @@ http://en.wikipedia.org/wiki/Digital_signature[Digital_signatures] == URI format -As mentioned Camel provides a pair of crypto endpoints to create and +As mentioned, Camel provides a pair of crypto endpoints to create and verify signatures ---------------------------- @@ -72,14 +72,14 @@ crypto:verify:name[?options] * `crypto:sign` creates the signature and stores it in the Header keyed by the constant `org.apache.camel.component.crypto.DigitalSignatureConstants.SIGNATURE`, -i.e. `"CamelDigitalSignature"`. +i.e., `"CamelDigitalSignature"`. * `crypto:verify` will read in the contents of this header and do the verification calculation. -In order to correctly function, the sign and verify process needs a pair +To correctly function, the sign and verify process needs a pair of keys to be shared, signing requiring a `PrivateKey` and verifying a `PublicKey` (or a `Certificate` containing one). Using the JCE it is -very simple to generate these key pairs but it is usually most secure to +very simple to generate these key pairs, but it is usually most secure to use a KeyStore to house and share your keys. The DSL is very flexible about how keys are supplied and provides a number of mechanisms. @@ -175,7 +175,7 @@ public class KeystoreConfig { } ---- -Again in Spring a ref is used to lookup an actual keystore instance. +Again in Spring, a ref is used to look up an actual keystore instance. === Changing JCE Provider and Algorithm @@ -203,18 +203,18 @@ In case you need to update the size of the buffer... === Supplying Keys dynamically. -When using a Recipient list or similar EIP the recipient of an exchange +When using a Recipient list or similar EIP, the recipient of an exchange can vary dynamically. Using the same key across all recipients may be neither feasible nor desirable. It would be useful to be able to specify signature keys dynamically on a per-exchange basis. The exchange could then be dynamically enriched with the key of its target recipient prior -to signing. To facilitate this the signature mechanisms allow for keys +to signing. To facilitate this, the signature mechanisms allow for keys to be supplied dynamically via the message headers below * `DigitalSignatureConstants.SIGNATURE_PRIVATE_KEY`, `"CamelSignaturePrivateKey"` * `DigitalSignatureConstants.SIGNATURE_PUBLIC_KEY_OR_CERT`, `"CamelSignaturePublicKeyOrCert"` -Even better would be to dynamically supply a keystore alias. Again the +Even better would be to dynamically supply a keystore alias. Again, the alias can be supplied in a message header * `DigitalSignatureConstants.KEYSTORE_ALIAS`, `"CamelSignatureKeyStoreAlias"` diff --git a/components/camel-crypto/src/main/docs/crypto-dataformat.adoc b/components/camel-crypto/src/main/docs/crypto-dataformat.adoc index a48018094a8..7d58adb8517 100644 --- a/components/camel-crypto/src/main/docs/crypto-dataformat.adoc +++ b/components/camel-crypto/src/main/docs/crypto-dataformat.adoc @@ -14,7 +14,7 @@ The Crypto Data Format integrates the Java Cryptographic Extension into Camel, allowing simple and flexible encryption and decryption of messages using Camel's familiar marshall -and unmarshal formatting mechanism. It assumes marshalling to mean +and unmarshal formatting mechanism. It assumes marshaling to mean encryption to cyphertext and unmarshalling to mean decryption back to the original plaintext. This data format implements only symmetric (shared-key) encryption and decyption. @@ -28,8 +28,8 @@ include::partial$dataformat-options.adoc[] == Basic Usage -At its most basic all that is required to encrypt/decrypt an exchange is a shared secret key. -If one or more instances of the Crypto data format are configured with this key the format can +At its most basic, all that is required to encrypt/decrypt an exchange is a shared secret key. +If one or more instances of the Crypto data format are configured with this key, the format can be used to encrypt the payload in one route (or part of one) and decrypted in another. For example, using the Java DSL as follows: @@ -69,7 +69,7 @@ In Spring the dataformat is configured first and then used in routes == Specifying the Encryption Algorithm -Changing the algorithm is a matter of supplying the JCE algorithm name. If you change the algorithm you will need to use a compatible key. +Changing the algorithm is a matter of supplying the JCE algorithm name. If you change the algorithm, you will need to use a compatible key. [source,java] ---------------------------------------------------------- @@ -93,7 +93,7 @@ A list of the available algorithms in Java 17 is available via the https://docs. Some crypto algorithms, particularly block algorithms, require configuration with an initial block of data known as an Initialization Vector. In the JCE this is passed as an AlgorithmParameterSpec when the Cipher is initialized. -To use such a vector with the CryptoDataFormat you can configure it with a byte[] containing the required data e.g. +To use such a vector with the CryptoDataFormat, you can configure it with a byte[] containing the required data, e.g. [source,java] ---------------------------------------------------------- @@ -120,6 +120,10 @@ or with spring, suppling a reference to a byte[] The same vector is required in both the encryption and decryption phases. As it is not necessary to keep the IV a secret, the DataFormat allows for it to be inlined into the encrypted data and subsequently read out in the decryption phase to initialize the Cipher. To inline the IV set the `Inline` flag. +[tabs] +==== +Java:: ++ [source,java] ---------------------------------------------------------- KeyGenerator generator = KeyGenerator.getInstance("DES"); @@ -139,8 +143,8 @@ from("direct:inline") .to("mock:unencrypted"); ---------------------------------------------------------- -or with spring. - +Spring XML:: ++ [source,xml] ---------------------------------------------------------- <crypto id="inline" algorithm="DES/CBC/PKCS5Padding" keyRef="desKey" initVectorRef="initializationVector" @@ -148,7 +152,9 @@ or with spring. <crypto id="inline-decrypt" algorithm="DES/CBC/PKCS5Padding" keyRef="desKey" inline="true" /> ---------------------------------------------------------- -For more information of the use of Initialization Vectors, consult +==== + +For more information about the use of Initialization Vectors, consult * http://en.wikipedia.org/wiki/Initialization_vector * http://www.herongyang.com/Cryptography/ @@ -156,8 +162,12 @@ For more information of the use of Initialization Vectors, consult == Hashed Message Authentication Codes (HMAC) -To avoid attacks against the encrypted data while it is in transit the CryptoDataFormat can also calculate a Message Authentication Code for the encrypted exchange contents based on a configurable MAC algorithm. The calculated HMAC is appended to the stream after encryption. It is separated from the stream in the decryption phase. The MAC is recalculated and verified against the transmitted version to ensure nothing was tampered with in transit. For more information on Message Authentica [...] +To avoid attacks against the encrypted data while it is in transit, the CryptoDataFormat can also calculate a Message Authentication Code for the encrypted exchange contents based on a configurable MAC algorithm. The calculated HMAC is appended to the stream after encryption. It is separated from the stream in the decryption phase. The MAC is recalculated and verified against the transmitted version to ensure nothing was tampered with in transit. For more information on Message Authentic [...] +[tabs] +==== +Java:: ++ [source,java] ---------------------------------------------------------- KeyGenerator generator = KeyGenerator.getInstance("DES"); @@ -172,15 +182,21 @@ from("direct:hmac") .to("mock:unencrypted"); ---------------------------------------------------------- -or with spring. - +Spring XML:: ++ [source,xml] ---------------------------------------------------------- <crypto id="hmac" algorithm="DES" keyRef="desKey" shouldAppendHMAC="true" /> ---------------------------------------------------------- -By default the HMAC is calculated using the HmacSHA1 mac algorithm though this can be easily changed by supplying a different algorithm name. See here for how to check what algorithms are available through the configured security providers +==== +By default, the HMAC is calculated using the HmacSHA1 mac algorithm, though this can be easily changed by supplying a different algorithm name. See here for how to check what algorithms are available through the configured security providers + +[tabs] +==== +Java:: ++ [source,java] ---------------------------------------------------------- KeyGenerator generator = KeyGenerator.getInstance("DES"); @@ -196,30 +212,35 @@ from("direct:hmac-algorithm") .to("mock:unencrypted"); ---------------------------------------------------------- -or with spring. - +Spring XML:: ++ [source,xml] ---------------------------------------------------------- <crypto id="hmac-algorithm" algorithm="DES" keyRef="desKey" macAlgorithm="HmacMD5" shouldAppendHMAC="true" /> ---------------------------------------------------------- +==== == Supplying Keys Dynamically -When using a Recipient list or similar EIP the recipient of an exchange can vary dynamically. -Using the same key across all recipients may neither be feasible or desirable. It would be useful to be able to specify -keys dynamically on a per exchange basis. The exchange could then be dynamically enriched with the key of its target -recipient before being processed by the data format. To facilitate this the DataFormat allows for keys to be supplied +When using a Recipient list or similar EIP, the recipient of an exchange can vary dynamically. +Using the same key across all recipients may neither be feasible nor desirable. It would be useful to be able to specify +keys dynamically on a per-exchange basis. The exchange could then be dynamically enriched with the key of its target +recipient before being processed by the data format. To facilitate this, the DataFormat allows for keys to be supplied dynamically via the message headers below * CryptoDataFormat.KEY "CamelCryptoKey" +[tabs] +==== +Java:: ++ [source,java] ---------------------------------------------------------- CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES", null); /** * Note: the header containing the key should be cleared after - * marshalling to stop it from leaking by accident and + * marshaling to stop it from leaking by accident and * potentially being compromised. The processor version below is * arguably better as the key is left in the header when you use * the DSL leaks the fact that camel encryption was used. @@ -237,17 +258,18 @@ from("direct:key-in-header-decrypt").unmarshal(cryptoFormat).process(new Process }).to("mock:unencrypted"); ---------------------------------------------------------- -or with spring: - +Spring XML:: ++ [source,xml] ---------------------------------------------------------- <crypto id="nokey" algorithm="DES" /> ---------------------------------------------------------- +==== == Dependencies -To use the xref:ROOT:crypto-component.adoc[Crypto] dataformat in your camel routes you +To use the xref:ROOT:crypto-component.adoc[Crypto] dataformat in your camel routes, you need to add the following dependency to your pom. [source,xml] diff --git a/components/camel-crypto/src/main/docs/pgp-dataformat.adoc b/components/camel-crypto/src/main/docs/pgp-dataformat.adoc index 723a2833ff6..c0427803b64 100644 --- a/components/camel-crypto/src/main/docs/pgp-dataformat.adoc +++ b/components/camel-crypto/src/main/docs/pgp-dataformat.adoc @@ -74,10 +74,10 @@ setting directly on the PGPDataFormat. setting directly on the PGPDataFormat. |`CamelPGPDataFormatNumberOfEncryptionKeys` |`Integer` |number of public keys used for encrypting the -symmectric key, set by PGPDataFormat during encryptiion process +symmetric key, set by PGPDataFormat during the encryption process |`CamelPGPDataFormatNumberOfSigningKeys` |`Integer` |number of private keys used for creating -signatures, set by PGPDataFormat during signing process +signatures, set by PGPDataFormat during the signing process |======================================================================= == Encrypting with PGPDataFormat @@ -90,14 +90,19 @@ The following sample performs signing + encryption, and then signature verification + decryption. It uses the same keyring for both signing and encryption, but you can obviously use different keys: +[tabs] +==== +Java:: ++ [source,java] ---- from("direct:pgp-encrypt") .marshal().pgp("file:pubring.gpg", "al...@example.com") .unmarshal().pgp("file:secring.gpg", "al...@example.com", "letmein"); ---- -Or using Spring: +Spring XML:: ++ [source,xml] ---- <route> @@ -107,7 +112,9 @@ Or using Spring: </route> ---- -=== To work with the previous example you need the following +==== + +=== Working with the previous example * A public keyring file which contains the public keys used to encrypt the data @@ -118,7 +125,7 @@ data === Managing your keyring To manage the keyring, I use the command line tools, I find this to be -the simplest approach in managing the keys. There are also Java +the simplest approach to managing the keys. There are also Java libraries available from http://www.bouncycastle.org/java.html[http://www.bouncycastle.org/java.html] if you would prefer to do it that way. @@ -135,13 +142,13 @@ Create your keyring, entering a secure password ------------- gpg --gen-key ------------- -If you need to import someone elses public key so that you can encrypt a file for them. +If you need to import someone else's public key so that you can encrypt a file for them. [source,bash] -------------------------- gpg --import <filename.key -------------------------- -If you are using GnuPG versions prior to 2.1, the key formats are stored in different files that can be used for the example. You can check if the required files exist by running the following command: +If you are using GnuPG versions prior to 2.1, the key formats are stored in different files that can be used, for example. You can check if the required files exist by running the following command: [source,bash] ----------------------------------------------- @@ -165,7 +172,7 @@ gpg --export-secret-keys > secring.gpg A PGP Data Formatter can decrypt/verify messages which have been encrypted by different public keys or signed by different private keys. -Just provide the corresponding private keys in the secret keyring, the +Provide the corresponding private keys in the secret keyring, the corresponding public keys in the public keyring, and the passphrases in the passphrase accessor. @@ -179,11 +186,11 @@ PGPPassphraseAccessor passphraseAccessor = new PGPPassphraseAccessorDefault(user PGPDataFormat pgpVerifyAndDecrypt = new PGPDataFormat(); pgpVerifyAndDecrypt.setPassphraseAccessor(passphraseAccessor); -// the method getSecKeyRing() provides the secret keyring as byte array containing the private keys -pgpVerifyAndDecrypt.setEncryptionKeyRing(getSecKeyRing()); // alternatively you can use setKeyFileName(keyfileName) -// the method getPublicKeyRing() provides the public keyring as byte array containing the public keys -pgpVerifyAndDecrypt.setSignatureKeyRing((getPublicKeyRing()); // alternatively you can use setSignatureKeyFileName(signatgureKeyfileName) -// it is not necessary to specify the encryption or signer User Id +// the method getSecKeyRing() provides the secret keyring as a byte array containing the private keys +pgpVerifyAndDecrypt.setEncryptionKeyRing(getSecKeyRing()); // alternatively, you can use setKeyFileName(keyfileName) +// the method getPublicKeyRing() provides the public keyring as a byte array containing the public keys +pgpVerifyAndDecrypt.setSignatureKeyRing((getPublicKeyRing()); // alternatively, you can use setSignatureKeyFileName(signatgureKeyfileName) +// it is not necessary to specify the encryption or signer User Id from("direct:start") ... @@ -192,7 +199,7 @@ from("direct:start") ------------------------------------------------------------------------------------------------------------------------------------------ * The functionality is especially useful to support the key exchange. If -you want to exchange the private key for decrypting you can accept for a +you want to exchange the private key for decrypting, you can accept for a period of time messages which are either encrypted with the old or new corresponding public key. Or if the sender wants to exchange his signer private key, you can accept for a period of time, the old or new signer @@ -201,14 +208,14 @@ key. public key which was used to encrypt the data. This Key ID can be used to locate the private key in the secret keyring to decrypt the data. The same mechanism is also used to locate the public key for verifying a -signature. Therefore you no longer must specify User IDs for the -unmarshaling. +signature. Therefore, you no longer must specify User IDs for the +unmarshalling. == Restricting the Signer Identities during PGP Signature Verification -If you verify a signature you not only want to verify the correctness of -the signature but you also want check that the signature comes from a -certain identity or a specific set of identities. Therefore it is +If you verify a signature, you not only want to verify the correctness of +the signature, but you also want to check that the signature comes from a +certain identity or a specific set of identities. Therefore, it is possible to restrict the number of public keys from the public keyring which can be used for the verification of a signature. @@ -225,7 +232,7 @@ which can be used for the verification of a signature. pgpVerifyWithSpecificKeysAndDecrypt.setPassword("my password"); // for decrypting with private key pgpVerifyWithSpecificKeysAndDecrypt.setKeyFileName(keyfileName); pgpVerifyWithSpecificKeysAndDecrypt.setSignatureKeyFileName(signatgureKeyfileName); - pgpVerifyWithSpecificKeysAndDecrypt.setSignatureKeyUserids(expectedSigUserIds); // if you have only one signer identity then you can also use setSignatureKeyUserid("expected Signer") + pgpVerifyWithSpecificKeysAndDecrypt.setSignatureKeyUserids(expectedSigUserIds); // if you have only one signer identity, then you can also use setSignatureKeyUserid("expected Signer") from("direct:start") ... @@ -233,16 +240,16 @@ from("direct:start") ... --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -* If the PGP content has several signatures the verification is +* If the PGP content has several signatures, the verification is successful as soon as one signature can be verified. -* If you do not want to restrict the signer identities for verification -then do not specify the signature key User IDs. In this case all public +* If you do not want to restrict the signer identities for verification, +then do not specify the signature key User IDs. In this case, all public keys in the public keyring are taken into account. == Several Signatures in One PGP Data Format The PGP specification allows that one PGP data format can contain -several signatures from different keys. Since Camel 2.13.3 it is +several signatures from different keys. Since Camel 2.13.3, it's been possible to create such kind of PGP content via specifying signature User IDs which relate to several private keys in the secret keyring. @@ -254,7 +261,7 @@ User IDs which relate to several private keys in the secret keyring. pgpSignAndEncryptSeveralSignerKeys.setKeyUserid(keyUserid); // for encrypting, you can also use setKeyUserids if you want to encrypt with several keys pgpSignAndEncryptSeveralSignerKeys.setKeyFileName(keyfileName); pgpSignAndEncryptSeveralSignerKeys.setSignatureKeyFileName(signatgureKeyfileName); - pgpSignAndEncryptSeveralSignerKeys.setSignaturePassword("sdude"); // here we assume that all private keys have the same password, if this is not the case then you can use setPassphraseAccessor + pgpSignAndEncryptSeveralSignerKeys.setSignaturePassword("sdude"); // here we assume that all private keys have the same password, if this is not the case, then you can use setPassphraseAccessor List<String> signerUserIds = new ArrayList<String>(); signerUserIds.add("company old key"); @@ -267,11 +274,11 @@ from("direct:start") ... ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -== Support of Sub-Keys and Key Flags in PGP Data Format Marshaler +== Support for Sub-Keys and Key Flags in PGP Data Format Marshaller An https://tools.ietf.org/html/rfc4880#section-12.1[OpenPGP V4 key] can have a primary key and sub-keys. The usage of the keys is indicated by -the so called https://tools.ietf.org/html/rfc4880#section-5.2.3.21[Key +the so-called https://tools.ietf.org/html/rfc4880#section-5.2.3.21[Key Flags]. For example, you can have a primary key with two sub-keys; the primary key shall only be used for certifying other keys (Key Flag 0x01), the first sub-key shall only be used for signing (Key Flag @@ -281,12 +288,12 @@ these Key Flags of the primary key and sub-keys in order to determine the right key for signing and encryption. This is necessary because the primary key and its sub-keys have the same User IDs. -== Support of Custom Key Accessors +== Support for Custom Key Accessors You can implement custom key accessors for encryption/signing. The above PGPDataFormat class selects in a certain predefined way the keys which should be used for signing/encryption or verifying/decryption. If -you have special requirements how your keys should be selected you +you have special requirements for how your keys should be selected, you should use the https://github.com/apache/camel/blob/main/components/camel-crypto/src/main/java/org/apache/camel/converter/crypto/PGPKeyAccessDataFormat.java[PGPKeyAccessDataFormat] class instead and implement the interfaces