A financial services client we took on last year had been running IPsec between their domain controllers and application servers for three years. Solid concept. The execution was a different story. During a network security assessment, we discovered their IPsec main mode cryptographic sets were negotiating with Triple DES, MD5, and Diffie-Hellman Group 1 — a 768-bit key exchange. In 2025. The configuration had been deployed by a contractor during the original IT buildout and never reviewed since. Their security team assumed IPsec meant encryption. What it actually meant, in practice, was a false sense of protection over a channel an attacker with moderate resources could crack offline.
This article walks through exactly how to build, audit, and modify IPsec main mode cryptographic sets using PowerShell’s NetSecurity module. We’ll cover what these sets actually control, which algorithms are acceptable, and how to verify what your environment is actually negotiating right now.
Why Main Mode Crypto Is Where Network Trust Gets Established
IPsec operates in two distinct phases. Quick mode handles the encryption of actual data traffic. Main mode — IKE Phase 1 — is where the two endpoints establish the security association (SA) that protects the subsequent key exchange. This is the foundation. If main mode negotiates with weak algorithms, everything downstream is compromised before a single byte of application data moves.
The negotiation works like this: the initiating endpoint sends an ordered list of cryptographic proposals. The responder picks the first proposal it can accept from that list. This means a strong responder policy is meaningless if the initiator offers weak proposals first and the responder’s policy window is permissive enough to accept them. The result is a silent downgrade — both endpoints think they’re running IPsec, both are technically correct, and the negotiated cipher suite belongs in a museum.
From a threat modeling perspective, MITRE ATT&CK T1040 (Network Sniffing) becomes significantly more actionable against environments where main mode is negotiating weak DH groups. Threat actors including APT28 and Sandworm have leveraged misconfigured VPN and IPsec implementations as part of lateral movement chains — not because they had a zero-day, but because the crypto was already soft enough to work offline against captured handshakes. The MITRE ATT&CK framework documents this persistence across campaigns going back years.
The problem in most managed environments isn’t ignorance of IPsec. It’s that IPsec configuration is set once during initial deployment and never revisited. Nobody runs a quarterly audit of cryptographic proposals in the active policy store. The negotiation keeps working — just with algorithms that should have been retired a decade ago.
The Architecture of a Main Mode Cryptographic Set
A main mode cryptographic set is an ordered list of proposals. Each proposal defines three parameters: the encryption algorithm, the hashing algorithm, and the Diffie-Hellman group for key exchange. These three values together define the protection for the IKE Phase 1 security association.
In Windows, you build this configuration in three steps using the NetSecurity module:
- Create individual proposal objects with
New-NetIPsecMainModeCryptoProposal - Assemble those proposals into an ordered set with
New-NetIPsecMainModeCryptoSet - Attach that set to a main mode rule with
New-NetIPsecMainModeRule
The ordering within the set is deliberate and consequential. Your strongest proposal goes first. A compliant peer that supports your preferred algorithms will negotiate there. Weaker fallback proposals exist for genuine compatibility requirements — not as defaults.
One architectural detail that trips up administrators unfamiliar with the NetSecurity module: you cannot pass a cryptographic set object directly into New-NetIPsecMainModeRule. The cmdlet requires the .Name property of the set — the GUID-based identifier — not the object itself. This is a common stumbling block when scripting this for the first time.
Building Cryptographic Proposals with New-NetIPsecMainModeCryptoProposal
The New-NetIPsecMainModeCryptoProposal cmdlet creates a single proposal object. It accepts three parameters: -Encryption, -Hash, and -KeyExchange. These map directly to the three mandatory parameters for main mode SA negotiation.
Here’s what a production-grade proposal stack looks like:
# Preferred proposal: AES256 + SHA384 + DH19 (NIST P-384 elliptic curve, 384-bit)
# This should be your first offer on any modern Windows Server environment
$proposal1 = New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA384 -KeyExchange DH19
# Second option: AES256 + SHA256 + DH14 (2048-bit MODP group)
# Acceptable fallback for environments that can't negotiate ECC
$proposal2 = New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA256 -KeyExchange DH14
# Legacy fallback only — document why this exists if you include it
# AES192 + SHA256 + DH14 is the floor for any new deployment
$proposal3 = New-NetIPsecMainModeCryptoProposal -Encryption AES192 -Hash SHA256 -KeyExchange DH14
Compare that to what appears in many production environments that were configured from older documentation or by contractors working from pre-2015 guides:
# What you should NOT deploy — legacy algorithms documented here for audit reference only
# DES3 = 168-bit Triple DES (NIST-deprecated since 2019)
# MD5 = broken hash function, collision attacks demonstrated since 2004
# DH1 = 768-bit prime group, practically factorable by well-resourced adversaries
$weakProposal = New-NetIPsecMainModeCryptoProposal -Encryption DES3 -Hash MD5 -KeyExchange DH1
MD5 as an HMAC in IKE negotiations is marginally stronger than MD5 for digital signatures — but the margin is not worth defending. DH Group 1 at 768 bits has been academically broken and is practically factorable at nation-state level since at least 2012. These aren’t theoretical concerns for compliance checkbox purposes. They’re real-world attack surface.
Assembling the Cryptographic Set
Once you have your proposal objects, New-NetIPsecMainModeCryptoSet assembles them into a named, ordered set. The set is what gets referenced by rules.
# Build a hardened main mode crypto set for production Windows Server environments
$proposal1 = New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA384 -KeyExchange DH19
$proposal2 = New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA256 -KeyExchange DH14
$proposal3 = New-NetIPsecMainModeCryptoProposal -Encryption AES192 -Hash SHA256 -KeyExchange DH14
# DisplayName is human-readable — make it descriptive and datestamped
# The .Name property (auto-generated GUID) is what rules reference
$mmCryptoSet = New-NetIPsecMainModeCryptoSet `
-DisplayName "Prod-MMCrypto-AES256-SHA384-DH19-$(Get-Date -Format yyyyMMdd)" `
-Proposal $proposal1, $proposal2, $proposal3
# Confirm the set was created and capture the Name property
$mmCryptoSet | Select-Object Name, DisplayName
The display name convention matters more than it seems in the moment. Six months from now, during an incident response or compliance audit, “Main Mode Crypto Set” is useless. A name that encodes the top-tier algorithm, the DH group, and the creation date gives your future self (or a new team member) an immediate read on what’s deployed without having to enumerate the proposals.
Linking the Crypto Set to a Main Mode Rule
The crypto set does nothing until it’s attached to a rule. New-NetIPsecMainModeRule creates that binding.
# Create the main mode rule and link it to the hardened crypto set
# Note: use $mmCryptoSet.Name (the GUID), not the object itself
$mainModeRule = New-NetIPsecMainModeRule `
-DisplayName "Enforce Strong Crypto - Production Servers" `
-MainModeCryptoSet $mmCryptoSet.Name
# Verify the rule exists and is linked to the correct set
Get-NetIPsecMainModeRule -DisplayName "Enforce Strong Crypto - Production Servers" |
Select-Object DisplayName, MainModeCryptoSet, Enabled
For environments where you’re managing authentication alongside the crypto policy — computer certificates for Phase 1, user credentials for Phase 2 — those get layered into the same rule via -Phase1AuthSet and -Phase2AuthSet parameters. The crypto set governs the negotiation algorithms. The auth sets govern identity. They’re independent concerns handled by the same rule object.
If you’re deploying this across a fleet of servers, script it and push it remotely. Running these cmdlets manually against 30 machines is how configuration drift enters the picture. The patterns in PowerShell CimSession: Remote Network Cmdlets at Scale apply directly here — wrap your deployment in a CimSession loop and you can standardize the crypto policy across an entire server estate in a single pass.
Auditing What’s Currently Negotiating
Before touching anything, audit the active state. This is step one on every engagement where IPsec is in scope.
# Pull all main mode crypto sets from the ACTIVE policy store
# ActiveStore = sum of all policy stores currently applied to this machine
# Without -PolicyStore, this returns the persistent store — not necessarily what's active
Get-NetIPsecMainModeCryptoSet -PolicyStore ActiveStore
# Get detailed proposal info for each active crypto set
Get-NetIPsecMainModeCryptoSet -PolicyStore ActiveStore | ForEach-Object {
$setName = $_.DisplayName
$_.Proposal | ForEach-Object {
[PSCustomObject]@{
CryptoSet = $setName
Encryption = $_.Encryption
Hash = $_.Hash
KeyExchange = $_.KeyExchange
}
}
}
The `-PolicyStore ActiveStore` flag is critical. Running without it queries the persistent store — what’s configured locally. The active store reflects what’s actually in effect, including any group policy overrides. These can differ significantly in domain-joined environments. Auditing the wrong store gives you false confidence.
# Flag any active crypto sets using deprecated DH groups
# DH1 (768-bit), DH2 (1024-bit), DH5 (1536-bit) are all high-risk findings
$weakSets = Get-NetIPsecMainModeCryptoSet -PolicyStore ActiveStore | Where-Object {
$_.Proposal | Where-Object { $_.KeyExchange -in @('DH1', 'DH2', 'DH5') }
}
if ($weakSets) {
Write-Warning "FINDING: $($weakSets.Count) crypto set(s) with deprecated DH groups detected"
$weakSets | Select-Object DisplayName, Name
} else {
Write-Host "No deprecated DH groups found in active main mode crypto sets" -ForegroundColor Green
}
During the financial services engagement, that second query returned three sets with DH1 proposals in the active store. The client’s security team had run annual penetration tests for two years — none of the assessors had looked at IPsec crypto negotiation. The sets had been there since initial deployment.
This is the kind of finding that makes an IT rollout plan necessary before remediation begins. If you’re standardizing IPsec policy across multiple sites as part of a broader IT rollout, document the before-state thoroughly before touching anything. You’ll need that baseline if something breaks.
Modifying Existing Crypto Sets Without Full Redeployment
When you need to harden an existing set — rather than start from scratch — Set-NetIPsecMainModeCryptoSet handles in-place modification. The typical workflow pulls the rule, retrieves its associated crypto set, modifies the proposals, and pushes back.
# Step 1: Get the target main mode rule
$rule = Get-NetIPsecMainModeRule -DisplayName "Legacy Main Mode Rule"
# Step 2: Get the crypto set associated with that rule
# Note: use Get-NetIPsecMainModeCryptoSet here, not Get-NetIPsecQuickModeCryptoSet
# These are distinct objects — mixing them is a common scripting error
$cryptoSet = $rule | Get-NetIPsecMainModeCryptoSet
# Step 3: Replace all proposals with hardened alternatives
$cryptoSet | Set-NetIPsecMainModeCryptoSet -Proposal `
(New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA384 -KeyExchange DH19), `
(New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA256 -KeyExchange DH14)
An alternative approach — useful when you need atomic replacement of a single proposal within a set rather than full replacement:
# Get the main mode rule and its crypto set
$mainModeRule = New-NetIPsecMainModeRule `
-DisplayName "MainModeRule" `
-MainModeCryptoSet (New-NetIPsecMainModeCryptoSet `
-DisplayName "MainModeCryptoSet" `
-Proposal (New-NetIPsecMainModeCryptoProposal -KeyExchange DH1), `
(New-NetIPsecMainModeCryptoProposal -KeyExchange DH14)).Name
$mainModeCryptoSet = $mainModeRule | Get-NetIPsecMainModeCryptoSet
# Swap the first proposal's key exchange from DH1 to DH19
$mainModeCryptoSet.Proposal[0] = New-NetIPsecMainModeCryptoProposal `
-Encryption AES256 -Hash SHA256 -KeyExchange DH19
# Push the change
$mainModeCryptoSet | Set-NetIPsecMainModeCryptoSet
One caveat worth flagging: modifying crypto sets affects only new SA negotiations. Existing established SAs continue using the algorithms they were negotiated with until they expire or are explicitly cleared. After pushing changes, clear existing SAs with Remove-NetIPsecMainModeSA if you need immediate enforcement rather than waiting for natural SA expiry.
Algorithm Selection: An Opinionated Position
If your organization is still accepting DH Group 1, DH Group 2, or MD5 in new deployments in 2025, you’re not balancing security against compatibility — you’re accepting a documented vulnerability to avoid doing the compatibility remediation work.
DH Group 1 (768-bit) and Group 2 (1024-bit) are broken against state-level adversaries and increasingly against criminal groups with access to cloud compute. MD5 has had collision attacks since 2004 and was fully broken by 2009. 3DES was formally deprecated by NIST in SP 800-131A Rev. 2 (2019). These aren’t theoretical deprecations waiting for a real-world incident to validate them. The real-world incidents happened. The NIST deprecations followed.
Here’s the algorithm tiering I use for Windows IPsec deployments:
- Preferred: AES256 + SHA384 + DH19 (or DH20/DH21 where supported)
- Acceptable: AES256 + SHA256 + DH14; AES192 + SHA256 + DH14
- Legacy only — document the exception and set a remediation date: AES128 + SHA1 + DH14
- Remove immediately: Anything using DES3, MD5, DH1, DH2, or DH5
The genuine caveat: some older VPN appliances and Windows Server 2003-era systems top out at DH Group 2 and 3DES. If these exist in your environment, the correct answer is hardware replacement — not continued use of broken crypto. That replacement may not be a fast path in production. If you’re carrying a documented exception, apply compensating controls: network segmentation, enhanced logging on those endpoints, and an actual target date for decommission. An undocumented exception is just a vulnerability with extra steps.
If you need a reference baseline, NIST SP 800-77 Rev. 1 covers IKE algorithm recommendations with specific approval windows. Cross-reference your active proposals against that guidance for a defensible compliance position.
Verification: Confirming What’s Actually Negotiating
Deploying a new crypto set is step one. Confirming it’s actually being used is step two — and most teams stop at step one.
# Inspect active main mode SAs to verify negotiated algorithms
# This shows what's actually running, not just what's configured
Get-NetIPsecMainModeSA | Select-Object `
LocalAddress, `
RemoteAddress, `
CipherTransformConstants, `
IntegrityTransformConstants, `
DHGroup, `
KeyLifetimeSeconds | Format-Table -AutoSize
Check the DHGroup, CipherTransformConstants, and IntegrityTransformConstants fields. If you deployed DH19 as your preferred proposal and you’re seeing DH1 in active SAs, the remote endpoint is forcing a downgrade — either their policy is more permissive than yours, or there’s a policy mismatch between what you think is deployed and what’s active. Both scenarios require investigation before you close the finding.
# Quick check: flag any active main mode SAs using deprecated DH groups
Get-NetIPsecMainModeSA | Where-Object { $_.DHGroup -in @('DH1', 'DH2', 'DH5') } |
Select-Object LocalAddress, RemoteAddress, DHGroup, CipherTransformConstants
For event-based monitoring, Windows logs IPsec main mode negotiations to the Security event log. Event ID 4650 captures main mode SA establishment in negotiation mode; Event ID 4651 captures establishment after a mode change. Build a SIEM detection rule against 4651 filtered for deprecated DH groups or cipher suites. This generates low noise and high signal — a negotiation event using DH1 in a hardened environment should fire an alert immediately.
This kind of detection-layer visibility aligns directly with the defense-in-depth approach outlined in the Windows Server Hardening: Stop Guessing, Start Baselining framework — instrument the controls you deploy so you know when they’re being bypassed.
Protecting High-Value Traffic Paths
IPsec main mode crypto hardening matters most on traffic paths that carry credentials, backup data, or replication streams. Backup traffic specifically is an underappreciated attack surface. A threat actor with a foothold in your network doesn’t need to attack your production systems if they can intercept or manipulate the backup channel — that traffic often carries credentials, database dumps, and configuration data in bulk.
For environments where backup servers are on a dedicated VLAN or reachable across a routed segment — including setups with a Veeam backup repository on a separate network — applying a hardened main mode crypto set to the IPsec policy governing that traffic path is a direct compensating control. It’s not a substitute for network segmentation, but it ensures that a passive attacker on the backup VLAN can’t silently downgrade the negotiation and read the stream.
For fleet-wide endpoint enforcement beyond server-to-server traffic, consider pushing IPsec crypto policy through Microsoft Intune rather than maintaining per-machine PowerShell scripts. The PowerShell approach is ideal for rapid remediation and server workloads. Intune scales to managed endpoints without requiring individual script deployment.
Practical Takeaway
Run Get-NetIPsecMainModeCryptoSet -PolicyStore ActiveStore against your environment today. Enumerate every proposal in every set. Flag anything using DH1, DH2, MD5, or 3DES. That’s your finding list.
Remediation sequence: build replacement proposals with New-NetIPsecMainModeCryptoProposal starting with AES256/SHA384/DH19, assemble them into a named set with New-NetIPsecMainModeCryptoSet, link the set to your main mode rule with New-NetIPsecMainModeRule or update an existing set with Set-NetIPsecMainModeCryptoSet. Verify active SAs with Get-NetIPsecMainModeSA after the change. Clear stale SAs with Remove-NetIPsecMainModeSA if you need immediate enforcement.
If your environment has a mix of modern and legacy endpoints and you’re not sure which endpoints are forcing weak crypto negotiation, that’s the conversation to have before you start removing fallback proposals. We’ve scoped and executed this kind of IPsec hardening assessment across environments of every size. Reach out at https://clients.sse.to/contact.php if you want a second set of eyes on what’s actually negotiating in your network before you commit to a remediation approach. Crypto misconfiguration rarely travels alone.


