Library dealing with parsing and cryptography to sign and verify DKIM signatures. It also provides DMARC verification and ARC (Authenticated Received Chain) support for Java-based mail processing workflows.
The mailet has been moved to James project: https://github.com/apache/james-project/tree/master/server/mailet/dkim
A full example is available in DKIMTest
Signing a mime message can be achieved using the following snippet
import java.io.InputStream;
import java.security.PrivateKey;
String signatureTemplate = "v=1; a=rsa-sha256; c=simple; d=messiah.edu; h=date:from:subject; q=dns/txt; s=selector2;";
PrivateKey privateKey = null;
DKIMSigner dkimSigner = new DKIMSigner(signatureTemplate, privateKey);
// You need to provide the input stream of the mime message, it will be parsed
// by mime4j
InputStream stream = null;
String signature = dkimSigner.sign(inputStream);
// `signature` contains the full header
// DKIM-Signature: a=rsa-sha256; q=dns/txt; b=Axa8s/g...U1SIw==; c=simple; s=selector2; d=messiah.edu; v=1; bh=6pQ...6g=; h=date:from:subject;More advanced usage such as including multiple signatures can be found in DKIMTest
Verifying a mime message DKIM signatures can be achieved using the following snippet. The verifier always verifies all the signatures.
import java.io.InputStream;
// You can override the resolver in the constructor, use your own
// implementation of a retriever or use multiple implementations using a
// `MultiplexingPublicKeyRecordRetriever`
PublicKeyRecordRetriever keyRecordRetriever = new DNSPublicKeyRecordRetriever();
DKIMVerifier verifier = new DKIMVerifier(keyRecordRetriever);
InputStream stream = null; // you need to provide the input stream of the mime message
List<SignatureRecord> verifiedSignatures = verifier.verify(stream);
// `verifiedSignatures` contains only the signatures that have successfully
// passed the validation.
// If you want to query all the results including all the failures, you can
// retrieve them from the verifier
List<Result> results = verifier.getResults();DMARC verification combines SPF and DKIM results with the RFC5322 From
domain and the domain DMARC policy.
import org.apache.james.dmarc.DMARCVerifier;
import org.apache.james.dmarc.DmarcValidationResult;
import org.apache.james.dmarc.PublicKeyRecordRetrieverDmarc;
import org.apache.james.mime4j.dom.Message;
PublicKeyRecordRetrieverDmarc recordRetriever = null;
Message message = null;
DMARCVerifier dmarcVerifier = new DMARCVerifier(recordRetriever);
DmarcValidationResult dmarcResult = dmarcVerifier.runDmarcCheck(
message,
"pass client-ip=192.0.2.1; envelope-from=sender@example.org",
"example.org",
"pass",
"example.org");
String authenticationResult = dmarcResult.toString();More complete DMARC examples can be found in DMARCTest.
ARC support adds RFC 8617 signing and validation for intermediaries that need to preserve authentication results across forwarding hops.
Generating ARC headers for a MIME message can be achieved using the following snippet.
import java.io.InputStream;
import java.security.PrivateKey;
import java.util.Map;
import org.apache.james.arc.ArcSetBuilder;
import org.apache.james.arc.PublicKeyRetrieverArc;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.message.DefaultMessageBuilder;
String amsTemplate = "i=; a=rsa-sha256; c=relaxed/relaxed; d=example.org; s=arc; t=; h=Subject:From:To; bh=; b=";
String sealTemplate = "i=; cv=; a=rsa-sha256; d=example.org; s=arc; t=; b=";
PrivateKey privateKey = null;
InputStream stream = null;
Message message = new DefaultMessageBuilder().parseMessage(stream);
ArcSetBuilder arcSetBuilder = new ArcSetBuilder(
privateKey,
amsTemplate,
sealTemplate,
"mx.example.org",
System.currentTimeMillis() / 1000);
PublicKeyRetrieverArc keyRecordRetriever = null;
Map<String, String> arcSet = arcSetBuilder.buildArcSet(
message,
"mail.example.org",
"sender@example.org",
"192.0.2.1",
keyRecordRetriever);
String authenticationResults = arcSet.get("Authentication-Results");
String arcAuthenticationResults = arcSet.get("ARC-Authentication-Results");
String arcMessageSignature = arcSet.get("ARC-Message-Signature");
String arcSeal = arcSet.get("ARC-Seal");The generated map contains the ARC headers for the current hop, ready to be added to the message.
Validating ARC headers on a MIME message can be achieved using the following snippet.
import java.io.InputStream;
import org.apache.james.arc.ARCChainValidator;
import org.apache.james.arc.ArcValidationOutcome;
import org.apache.james.arc.PublicKeyRetrieverArc;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.message.DefaultMessageBuilder;
PublicKeyRetrieverArc keyRecordRetriever = null;
InputStream stream = null;
Message message = new DefaultMessageBuilder().parseMessage(stream);
ARCChainValidator arcChainValidator = new ARCChainValidator(keyRecordRetriever);
ArcValidationOutcome validation = arcChainValidator.validateArcChain(message);
String chainValidation = validation.getResult().toString();
String description = validation.getDescription();More complete ARC usage can be found in ARCTest.
ARC functionality is covered by tests in ARCTest. The coverage is based on the ARC protocol requirements from RFC 8617 and on the public ValiMail ARC test suite. The tests exercise ARC set creation, chain validation, ARC-Seal verification, ARC-Message-Signature canonicalization, body hash handling, required tag validation, and malformed or tampered ARC header cases.
This distribution includes cryptographic software. The country in
which you currently reside may have restrictions on the import,
possession, use, and/or re-export to another country, of
encryption software. BEFORE using any encryption software, please
check your country's laws, regulations and policies concerning the
import, possession, or use, and re-export of encryption software, to
see if this is permitted. See http://www.wassenaar.org for more
information.
The U.S. Government Department of Commerce, Bureau of Industry and
Security (BIS), has classified this software as Export Commodity
Control Number (ECCN) 5D002.C.1, which includes information security
software using or performing cryptographic functions with asymmetric
algorithms. The form and manner of this Apache Software Foundation
distribution makes it eligible for export under the License Exception
ENC Technology Software Unrestricted (TSU) exception (see the BIS
Export Administration Regulations, Section 740.13) for both object
code and source code.
The following provides more details on the included cryptographic
software:
- jDKIM includes code designed to work with Java SE Security
Export classifications and source links can be found
at http://www.apache.org/licenses/exports/.