Class Dkim
- All Implemented Interfaces:
AutoCloseable
Sign and verify MIME email with DKIM signatures.
Chilkat.Dkim is the Chilkat class for applying and verifying
DKIM signatures on MIME email data. It supports DKIM signing with
rsa-sha256 or rsa-sha1, configurable
canonicalization, selectable signed headers, signature counting, DNS
public-key lookup, public-key caching, public-key prefetching, and detailed
verification reporting through VerifyInfo.
DKIM signing
Add DKIM signatures to MIME messages using a private key, selector, signing domain, canonicalization settings, and selected headers.
Signed header selection
Choose which message headers are protected by the signature and control
their order in the generated h= tag.
Signature verification
Verify one or more signatures in a MIME message and determine whether the signed content, headers, and public key match.
Canonicalization control
Configure body and header canonicalization so signing and verification match the requirements of the sending domain and receiving systems.
DNS public keys
Retrieve DKIM public keys from DNS, prefetch keys when useful, and cache public keys to reduce repeated DNS lookups.
Verification diagnostics
Use VerifyInfo and related status information to understand
which signatures were found, which were checked, and why verification
succeeded or failed.
Common pattern:
To sign, provide the MIME message, signing domain, selector, private key,
canonicalization choices, and the headers to include in the signature. To
verify, pass the received MIME message to Dkim, allow the class
to locate the signature and public key, and inspect VerifyInfo
for detailed results.
For an extended overview, see Dkim Class Overview.
</section>
Event-capable: long-running methods report progress through a ProgressListener installed
with setProgressListener(ProgressListener), onAbortCheck(BooleanSupplier),
onPercentDone(IntPredicate) or onProgressInfo(BiConsumer).
Instances hold a native Chilkat object: close them with ChilkatObject.close() (try-with-resources) when
done; an unclosed instance is freed when it becomes unreachable.
- See Also:
- Online reference
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidCreates aDKIM-Signatureheader and prepends it to the complete MIME message stored inmimeData.voiddkimVerify(int sigIndex, BinData mimeData)Verifies theDKIM-Signatureheader at zero-basedsigIndexin the complete MIME message stored inmimeData.booleanSet totrueto request cancellation of a currently running operation.Specifies the signing algorithm written to thea=tag of a newly createdDKIM-Signatureheader.intControls the maximum number of bytes from the canonicalized message body used when computing the DKIM body hash.Specifies one DKIM canonicalization algorithm to use for both the signed header fields and the message body.Specifies the signing domain written verbatim to thed=tag of the generatedDKIM-Signatureheader.A colon-separated list of header field names to include in the DKIM signature.Specifies the selector written verbatim to thes=tag of a generated DKIM signature.intSpecifies the interval, in milliseconds, betweencallbacks during methods that support periodic cancellation checks.AbortCheckReturns the installed listener, ornull.Contains JSON describing the most recent call to.dkimVerify(int, BinData)voidloadPublicKey(String selector, String domain, String publicKey)Loads and caches an RSA public key in thisDkimobject for the exactselectoranddomainstrings.voidloadPublicKeyFile(String selector, String domain, String publicKeyFilepath)Loads an RSA public key from the local file atpublicKeyFilepathand caches it in thisDkimobject for the exactselectoranddomainstrings.intnumDkimSigs(BinData mimeData)Returns the number of header fields namedDKIM-SignatureinmimeData.voidonAbortCheck(BooleanSupplier callback)Installs a listener whose only callback isabortCheck: called everyHeartbeatMsmilliseconds during a long-running method; returntrueto abort it.voidonPercentDone(IntPredicate callback)Installs a listener whose only callback ispercentDone: called with the completion percentage (0..100) as a long-running method progresses; returntrueto abort it.voidonProgressInfo(BiConsumer<String,String> callback)Installs a listener whose only callback isprogressInfo: called with a name/value pair of progress information as a long-running method proceeds.voidprefetchPublicKey(String selector, String domain)Retrieves the DKIM public key from DNS and caches it in thisDkimobject for the exactselectoranddomainstrings.voidsetAbortCurrent(boolean value)Sets theAbortCurrentproperty; seegetAbortCurrent().voidsetDkimAlg(String value)Sets theDkimAlgproperty; seegetDkimAlg().voidsetDkimBodyLengthCount(int value)Sets theDkimBodyLengthCountproperty; seegetDkimBodyLengthCount().voidsetDkimCanon(String value)Sets theDkimCanonproperty; seegetDkimCanon().voidsetDkimDomain(String value)Sets theDkimDomainproperty; seegetDkimDomain().voidsetDkimHeaders(String value)Sets theDkimHeadersproperty; seegetDkimHeaders().voidsetDkimPrivateKey(PrivateKey privateKey)Copies the RSA key fromprivateKeyinto this object for subsequent calls to.dkimSign(BinData)voidsetDkimSelector(String value)Sets theDkimSelectorproperty; seegetDkimSelector().voidsetHeartbeatMs(int value)Sets theHeartbeatMsproperty; seegetHeartbeatMs().voidsetProgressListener(ProgressListener listener)Installs the listener that receives this object's progress events (abortCheck,percentDone,progressInfo) during its long-running methods; replaces any listener or lambda installed before;nullremoves it.Methods inherited from class com.chilkatsoft.chilkat2.ChilkatObject
close, getDebugLogFilePath, getLastErrorHtml, getLastErrorText, getLastErrorXml, getLastMethodSuccess, getVerboseLogging, getVersion, isClosed, setDebugLogFilePath, setLastMethodSuccess, setVerboseLogging, toString
-
Constructor Details
-
Dkim
public Dkim()Creates a newDkimobject.
-
-
Method Details
-
getAbortCurrent
public boolean getAbortCurrent()Set totrueto request cancellation of a currently running operation. A synchronous operation can be cancelled from another thread by setting this property on the same object. Methods that complete quickly or do not periodically check for cancellation may finish before the request is observed. Cancellation behavior: Treat this as a cancellation request rather than a guarantee of immediate termination. After the method returns, use the method's normal return value and diagnostic properties to determine the outcome.- Returns:
- the value of the
AbortCurrentproperty
-
setAbortCurrent
public void setAbortCurrent(boolean value)Sets theAbortCurrentproperty; seegetAbortCurrent().- Parameters:
value- the new value
-
getDkimAlg
Specifies the signing algorithm written to thea=tag of a newly createdDKIM-Signatureheader. The default isrsa-sha256.Value Behavior
rsa-sha256RSA signing with a SHA-256 digest. This is the recommended value.rsa-sha1Legacy RSA signing with a SHA-1 digest. Use only when an older system specifically requires it.The value is trimmed and compared case-insensitively. The recognized values are
rsa-sha256andrsa-sha1. An empty or unrecognized value is normalized torsa-sha256rather than rejected.- Returns:
- the value of the
DkimAlgproperty
-
setDkimAlg
Sets theDkimAlgproperty; seegetDkimAlg().- Parameters:
value- the new value (notnull)
-
getDkimBodyLengthCount
public int getDkimBodyLengthCount()Controls the maximum number of bytes from the canonicalized message body used when computing the DKIM body hash. The default is0.Value Behavior
0Hashes the complete canonicalized body and omits the DKIMl=tag.Positive and less than the canonicalized body length Hashes the specified number of bytes and emits
l=with that value.Positive and greater than the canonicalized body length Hashes the complete canonicalized body and emits
l=containing the actual canonicalized body length.Negative
-1hashes the complete canonicalized body and emitsl=containing the actual canonicalized body length.When a generated signature contains
l=, verification hashes only the indicated prefix of the canonicalized body. Content appended after that signed prefix does not invalidate the signature.Security note: Partial-body signatures allow unsigned content to be appended after the signed portion. Signing the complete body by using
0is normally preferred.- Returns:
- the value of the
DkimBodyLengthCountproperty
-
setDkimBodyLengthCount
public void setDkimBodyLengthCount(int value)Sets theDkimBodyLengthCountproperty; seegetDkimBodyLengthCount().- Parameters:
value- the new value
-
getDkimCanon
Specifies one DKIM canonicalization algorithm to use for both the signed header fields and the message body. The default isrelaxed.Value Generated
c=value Behaviorsimplesimple/simplePreserves formatting closely. Small changes in whitespace or header folding can invalidate the signature.relaxedrelaxed/relaxedNormalizes defined whitespace and header-name differences.The value is trimmed and compared case-insensitively. This property does not accept a header/body pair such as
relaxed/simpleorsimple/relaxed. Pair values, an empty string, and other unrecognized values are normalized torelaxedrather than rejected.Canonicalization background: DKIM signs a canonicalized representation of the message. The signer and verifier must apply the same header and body canonicalization rules.
- Returns:
- the value of the
DkimCanonproperty
-
setDkimCanon
Sets theDkimCanonproperty; seegetDkimCanon().- Parameters:
value- the new value (notnull)
-
getDkimDomain
Specifies the signing domain written verbatim to thed=tag of the generatedDKIM-Signatureheader. The corresponding public key is normally published beneath the DNS name formed fromand this domain.getDkimSelector()Set this property to a nonempty, syntactically valid domain before calling
. If this property is empty,dkimSign(BinData)DkimSignreturnsfalsewithout modifying the MIME data. A nonempty value is not otherwise validated or normalized during signing; uppercase letters, surrounding whitespace, a trailing dot, and Unicode characters are emitted as supplied.Caller responsibility: Supply the domain in the exact form required in the signature. For an internationalized domain, use its ASCII/Punycode form.
DkimSigndoes not check DNS and does not confirm that the configured private key matches the public key published for this domain. DKIM and DMARC: DKIM verification does not required=to equal the visibleFromdomain. DMARC separately evaluates alignment between the authenticated DKIM domain and the message'sFromdomain.- Returns:
- the value of the
DkimDomainproperty
-
setDkimDomain
Sets theDkimDomainproperty; seegetDkimDomain().- Parameters:
value- the new value (notnull)
-
getDkimHeaders
A colon-separated list of header field names to include in the DKIM signature. The list is written to the signature'sh=tag in the same order. The default is:mime-version:date:message-id:subject:from:to:content-type
Header-name matching is case-insensitive. For each occurrence of a name in this list, Chilkat selects the next matching header field from the bottom of the message header block upward, as required by DKIM. For example, if the message contains two
Subjectfields, listingsubjectonce signs the bottommost field, while listing it twice signs both fields.If a listed occurrence has no corresponding field in the message, the absent field is still included in the signing calculation. Repeating a name more times than it occurs can therefore implement DKIM oversigning and prevent a matching field from being inserted later without invalidating the signature.
- Use colon-separated field names without surrounding spaces.
- Include
from; DKIM requires theFromfield to be signed, butdoes not enforce this requirement or add it automatically.dkimSign(BinData) - An empty list and names of missing fields are accepted rather than rejected.
- Avoid transport-added or frequently modified fields such as
ReceivedandReturn-Path.
Repeated names: Repeated existing headers are signed successively from bottom to top. Repeated absent occurrences are useful for oversigning.
- Returns:
- the value of the
DkimHeadersproperty
-
setDkimHeaders
Sets theDkimHeadersproperty; seegetDkimHeaders().- Parameters:
value- the new value (notnull)
-
getDkimSelector
Specifies the selector written verbatim to thes=tag of a generated DKIM signature. The selector andform the DNS name used to locate the public key:getDkimDomain()selector._domainkey.signing-domain
For example, selector
brisbaneand domainchilkatsoft.comproducebrisbane._domainkey.chilkatsoft.com.Supply only the selector. Do not include
._domainkey.or the signing domain. If this property is empty,returnsdkimSign(BinData)falsewithout modifying the MIME data. A nonempty value is not otherwise validated or normalized during signing; for example, a complete DNS name is emitted as supplied rather than reduced to a selector.Caller responsibility: Use a nonempty selector consisting of valid DNS selector labels. The private key configured by
must match the public key published for this selector and domain.setDkimPrivateKey(PrivateKey)- Returns:
- the value of the
DkimSelectorproperty
-
setDkimSelector
Sets theDkimSelectorproperty; seegetDkimSelector().- Parameters:
value- the new value (notnull)
-
getHeartbeatMs
public int getHeartbeatMs()Specifies the interval, in milliseconds, betweencallbacks during methods that support periodic cancellation checks. Set toAbortCheck0to disable these callbacks. The default is0.invokesprefetchPublicKey(String, String)AbortCheckwhile performing its DNS lookup. Setting this property to1and requesting cancellation from the first callback causesPrefetchPublicKeyto returnfalse.Responsiveness and overhead: A smaller interval can make cancellation more responsive, but it also increases callback overhead. Methods that finish quickly may complete before any callback occurs.
- Returns:
- the value of the
HeartbeatMsproperty
-
setHeartbeatMs
public void setHeartbeatMs(int value)Sets theHeartbeatMsproperty; seegetHeartbeatMs().- Parameters:
value- the new value
-
getVerifyInfo
Contains JSON describing the most recent call to. The property is initially an empty string and is replaced or cleared by each verification attempt.dkimVerify(int, BinData)Member Meaning
domainThe signature'sd=value.selectorThe signature'ss=value.publicKeyThe Base64 public-key value obtained from DNS. This member is present when verification performs an automatic DNS lookup and may be absent when a preloaded or prefetched key is used.canonicalizationThe header/body canonicalization pair fromc=.algorithmThe signature algorithm froma=.signedHeadersThe signed-header list fromh=.fromSignedIndicates whether the requiredFromfield name is included in the signed-header list.expectedBodyHashThe Base64 body hash obtained from the signature'sbh=tag.computedBodyHashThe Base64 body hash computed from the received message, applying the signature's canonicalization and optionall=body-length limit.bodyHashVerifiedThe string"yes"when the computed body hash matchesbh=, or"no"when it does not.verifiedThe string"yes"for a valid signature or"no"for a completed verification that failed.{ "domain": "chilkatsoft.com", "selector": "brisbane", "canonicalization": "relaxed/relaxed", "algorithm": "rsa-sha256", "signedHeaders": "from:to:subject:date:message-id", "fromSigned": "yes", "expectedBodyHash": "...", "computedBodyHash": "...", "bodyHashVerified": "yes", "verified": "yes" }Not every member is present in every result. For malformed signatures, unsupported algorithms, missing signatures, DNS failures, or an out-of-range index, the value may be an empty string,
{}, or a partial object withoutverified. Therefore, first check the return value ofDkimVerify, and then treat individual JSON members as optional.Authentication scope: A valid DKIM signature shows that the verified signed content was produced by an entity possessing the private key for the authenticated domain. It does not by itself prove the identity of the human sender or establish DMARC alignment.
- Returns:
- the value of the
VerifyInfoproperty (read-only)
-
dkimSign
Creates aDKIM-Signatureheader and prepends it to the complete MIME message stored inmimeData. TheBinDatais modified in place.Before calling this method:
- Construct the final MIME message, including all headers, transfer encodings, MIME boundaries, and body bytes.
- Use RFC 5322 line endings. The MIME header and body must use CRLF and be separated by
. LF-only and CR-only MIME are not normalized and cause the method to fail. - Set
,getDkimDomain(),getDkimSelector(),getDkimAlg(), andgetDkimCanon().getDkimHeaders() - Load the RSA private key by calling
.setDkimPrivateKey(PrivateKey)
On success, the generated header contains
v=1,a=,c=,q=dns/txt,d=,s=,h=,bh=, andb=. Whenis nonzero, the header also containsgetDkimBodyLengthCount()l=. The generated header does not includet=,x=, ori=. Signing the same bytes twice with the same settings and key produced identical output.An empty body, a body without a final newline, and body data containing NUL or other binary bytes are accepted. An empty
, an emptygetDkimDomain(), missing or invalid private-key state, or malformed MIME causes the method to returngetDkimSelector()falsewithout changingmimeData.Existing signatures: A new signature is prepended and existing
DKIM-Signaturefields are preserved. Signature indexes therefore follow top-to-bottom order: the newly added signature is index0, and older signatures shift to higher indexes. Each signature can be verified independently. Sign the final representation: Send the signed bytes directly. Parsing and regenerating the message, changing line endings, refolding signed headers, changing transfer encodings, or editing the signed body can invalidate the signature.- Parameters:
mimeData- themimeDataargument (notnull)- Throws:
ChilkatException- if the operation fails;ChilkatException.getLastErrorText()says why
-
dkimVerify
Verifies theDKIM-Signatureheader at zero-basedsigIndexin the complete MIME message stored inmimeData. Signatures are indexed in top-to-bottom header order. Useto obtain the count.numDkimSigs(BinData)Chilkat first looks for a public key cached under the exact selector/domain strings. If no exact match exists, it synchronously retrieves the TXT record at
selector._domainkey.domain. The method does not modifymimeData.Return value Meaning
trueThe selected signature was successfully verified, including its body hash and signed headers.falseThe signature was invalid, or verification could not be completed because of an invalid index, malformed signature, unsupported algorithm, missing key, DNS failure, or another operational error.Verification compares the signature's
bh=value with the hash computed from the canonicalized body. When the signature containsl=, only the indicated number of canonicalized body bytes are included, so content appended after the signed prefix does not cause a body-hash failure.After the call, inspect
. A completed verification failure normally containsgetVerifyInfo()"verified":"no". A body-hash mismatch also contains"bodyHashVerified":"no"with the expected and computed hashes. Operational and parsing failures may leave an empty string,{}, or a partial JSON object; useLastErrorTextfor the detailed reason.Multiple signatures: Verify each signature independently. One valid signature does not imply that every signature on the message is valid.
- Parameters:
sigIndex- thesigIndexargumentmimeData- themimeDataargument (notnull)- Throws:
ChilkatException- if the operation fails;ChilkatException.getLastErrorText()says why
-
loadPublicKey
Loads and caches an RSA public key in thisDkimobject for the exactselectoranddomainstrings. A lateruses the cached key when the signature contains the same selector and domain; otherwise verification falls back to DNS.dkimVerify(int, BinData)publicKeycontains a textual key representation. Supported formats include:- PEM X.509 SubjectPublicKeyInfo (
-----BEGIN PUBLIC KEY-----) - PEM PKCS#1 RSA public key (
-----BEGIN RSA PUBLIC KEY-----) - XML RSA key data
- RSA JWK JSON
The selector/domain cache key is case-sensitive. Loading a key for uppercase values does not satisfy a lowercase signature. A successful later load for the same pair replaces the earlier key. If a later load fails because the supplied key text is invalid, the previously cached key remains available.
Typical use: Preload a trusted public key for testing before DNS publication or for a controlled verification environment. The key data is copied into the cache; the input string does not need to remain available after this method returns.
- Parameters:
selector- theselectorargument (notnull)domain- thedomainargument (notnull)publicKey- thepublicKeyargument (notnull)- Throws:
ChilkatException- if the operation fails;ChilkatException.getLastErrorText()says why
- PEM X.509 SubjectPublicKeyInfo (
-
loadPublicKeyFile
Loads an RSA public key from the local file atpublicKeyFilepathand caches it in thisDkimobject for the exactselectoranddomainstrings. The file is read during this call.Supported formats include PEM X.509 SubjectPublicKeyInfo, PEM PKCS#1 RSA public key, binary DER PKCS#1 RSA public key, XML RSA key data, and RSA JWK JSON. The selector/domain cache key is case-sensitive.
A later successful load for the same selector/domain pair replaces the earlier cached key. If no exact cached key is present when
runs, Chilkat performs its normal DNS lookup.dkimVerify(int, BinData)Path and trust:
publicKeyFilepathis a path in the local filesystem. Load only keys from a trusted source because the cached key determines which signatures are accepted for that selector and domain.- Parameters:
selector- theselectorargument (notnull)domain- thedomainargument (notnull)publicKeyFilepath- thepublicKeyFilepathargument (notnull)- Throws:
ChilkatException- if the operation fails;ChilkatException.getLastErrorText()says why
-
numDkimSigs
Returns the number of header fields namedDKIM-SignatureinmimeData. Header-name matching is case-insensitive. The method counts matching fields without validating the signature syntax; for example, a malformedDKIM-Signature: nonsensefield is still counted.The indexes used by
are zero-based and follow top-to-bottom header order. The method returnsdkimVerify(int, BinData)0when no matching header is found, including for an empty message. It does not modifymimeData.Counting versus validation: This method is a header count, not a MIME or DKIM validation step. A positive result does not mean that any counted signature is well formed or verifiable.
- Parameters:
mimeData- themimeDataargument (notnull)- Returns:
- the result (see
ChilkatObject.getLastMethodSuccess()where the description mentions failure)
-
prefetchPublicKey
Retrieves the DKIM public key from DNS and caches it in thisDkimobject for the exactselectoranddomainstrings. The TXT lookup is made for:selector._domainkey.domain
The method returns
truewhen the DNS lookup and public-key loading succeed. Repeated calls for a cached pair can complete without another observable lookup. A successful prefetch replaces an existing manually loaded key for the same selector/domain pair.also performs this DNS lookup automatically when no exact cached key is available. Prefetching is useful when several messages will be verified for the same selector and domain.dkimVerify(int, BinData)Cancellation: This method supports
callbacks according toAbortCheck. When the callback requests cancellation, the method returnsgetHeartbeatMs()falseand the DNS lookup is aborted. Key rotation: The selector identifies a particular published key. When a sender begins using a new selector, prefetch the new selector separately.- Parameters:
selector- theselectorargument (notnull)domain- thedomainargument (notnull)- Throws:
ChilkatException- if the operation fails;ChilkatException.getLastErrorText()says why
-
setDkimPrivateKey
Copies the RSA key fromprivateKeyinto this object for subsequent calls to. The sourcedkimSign(BinData)PrivateKeyobject may be destroyed after this method returns successfully, and the configured key can be reused for multiple signatures.A later successful call replaces the previously configured signing key. A failed call with an empty or unrecognized key clears the usable signing-key state; a subsequent
DkimSignfails until a valid key is set again.Key matching: The private key must correspond to the public key published at
selector._domainkey.domain, usingandgetDkimSelector(). This method does not check DNS or confirm the match.getDkimDomain()- Parameters:
privateKey- theprivateKeyargument (notnull)- Throws:
ChilkatException- if the operation fails;ChilkatException.getLastErrorText()says why
-
setProgressListener
Installs the listener that receives this object's progress events (abortCheck,percentDone,progressInfo) during its long-running methods; replaces any listener or lambda installed before;nullremoves it.- Parameters:
listener- the listener, ornull- Throws:
IllegalStateException- if called from inside one of this object's own callbacks
-
getProgressListener
Returns the installed listener, ornull.- Returns:
- the listener installed with
setProgressListener(ProgressListener)or one of theon...methods
-
onAbortCheck
Installs a listener whose only callback isabortCheck: called everyHeartbeatMsmilliseconds during a long-running method; returntrueto abort it. Replaces any listener installed before.- Parameters:
callback- the callback, ornullto remove the listener
-
onPercentDone
Installs a listener whose only callback ispercentDone: called with the completion percentage (0..100) as a long-running method progresses; returntrueto abort it. Replaces any listener installed before.- Parameters:
callback- the callback, ornullto remove the listener
-
onProgressInfo
Installs a listener whose only callback isprogressInfo: called with a name/value pair of progress information as a long-running method proceeds. Replaces any listener installed before.- Parameters:
callback- the callback, ornullto remove the listener
-