---
title: Generate SSO handshake payload
summary: Encrypts session-transfer data and produces a signed, envelope-encrypted SSO payload for the US Bank ePay service.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Services.WebServices.Epay
reference_type: package
operation_id: OP-EPAY-01
trigger: Caller invokes USBank.GetSSOData(sessionTransferData)
---

# Generate SSO handshake payload

This operation builds the single sign-on (SSO) handshake payload that this library sends to US Bank's ePay service. It AES-encrypts the caller-supplied session-transfer data, wraps the AES key with US Bank's RSA public certificate, signs the encrypted data with SAIF's own RSA private certificate, and returns the four resulting values bundled in a serializable DTO.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-EPAY-01 |
| **Trigger** | Caller invokes `USBank.GetSSOData(sessionTransferData)` |
| **Inputs** | `sessionTransferData` (String) |
| **Outputs** | `AdminSingleSignOnData` DTO containing Base64-encoded encrypted data, wrapped symmetric key, IV, and digital signature |
| **Primary components** | `USBank.GetSSOData`, `USBank.LoadUSBankCert`, `USBank.LoadSaifAdminCert`, `USBank.GetCertificateParameters`, `AdminSingleSignOnData` |
| **Entry point** | `Services\SAIF.Services.WebServices.Epay\WebService\USBank.vb` |

## Steps

1. AES-256 encrypt `sessionTransferData` (`SAIFCrypto.AES.Encrypt`), producing ciphertext (`encryptedData`), a generated symmetric key, and an initialization vector (IV).
2. Resolve the US Bank SSO certificate's distinguished name (DN) by calling `GetCertificateParameters("usBankEPaySSOCertDN")`, which reads the `usBankEPaySSOCertDN` configuration setting via `AppGlobal.EnvironmentService.GetConfigSetting` and JSON-deserializes it into DN key/value pairs, then builds the DN string with `SAIFCrypto.Certificates.GetDistinguishedName` ([BR-003](../business-rules.md#br-003-certificate-dn-composition-is-externally-configurable)).
3. Load the US Bank SSO certificate (`X509Certificate2`) from the `LocalMachine\Root` certificate store by the resolved DN (`LoadUSBankCert`) ([BR-001](../business-rules.md#br-001-fail-fast-on-missing-signingencryption-certificates)).
   - On failure (certificate not found): throw `ApplicationException("USBank Cert not found.")`, aborting the handshake immediately — the RSA key-wrap step never executes.
4. RSA-encrypt the AES symmetric key with the US Bank certificate's public key (`SAIFCrypto.Certificates.EncryptWithCertPublicKey`), producing the wrapped key.
5. Discard the raw AES symmetric key from memory by setting it to `Nothing` ([BR-002](../business-rules.md#br-002-symmetric-key-material-is-not-retained-on-the-dto)).
6. Resolve the SAIF admin authentication certificate's DN by calling `GetCertificateParameters("usBankEPayAuthenticationAdminCertDN")`, following the same configuration-lookup-and-deserialize path as step 2 ([BR-003](../business-rules.md#br-003-certificate-dn-composition-is-externally-configurable)).
7. Load the SAIF admin authentication certificate from the `LocalMachine\My` certificate store by the resolved DN (`LoadSaifAdminCert`) ([BR-001](../business-rules.md#br-001-fail-fast-on-missing-signingencryption-certificates)).
   - On failure (certificate not found): throw `ApplicationException("SAIF cert not found.")`, aborting the handshake immediately — the signing step never executes.
8. Digitally sign the AES-encrypted data (`encryptedData`) with the SAIF admin certificate's private key (`SAIFCrypto.Certificates.SignWithCertPrivateKey`), producing the signature.
9. Construct and return a new `AdminSingleSignOnData`, whose constructor stores the encrypted data, wrapped key, IV, and signature as private byte-array fields; its public properties expose each as a Base64-encoded string and cannot be reassigned after construction, since each property's `Private Set` discards the assigned value instead of storing it ([BR-002](../business-rules.md#br-002-symmetric-key-material-is-not-retained-on-the-dto)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Start: sessionTransferData]) --> AES[AES-256 encrypt payload]
	AES --> LoadUsBankDN[Resolve US Bank cert DN<br>via usBankEPaySSOCertDN config]
	LoadUsBankDN --> LoadUsBankCert[Load US Bank cert<br>from LocalMachine Root]
	LoadUsBankCert --> CertCheck{US Bank cert<br>found?}
	CertCheck -->|No| ErrUSBank([Throw ApplicationException:<br>USBank Cert not found.])
	CertCheck -->|Yes| RSAWrap[RSA-wrap AES key with<br>US Bank public key]
	RSAWrap --> DiscardKey[Discard raw symmetric key]
	DiscardKey --> LoadSaifDN[Resolve SAIF admin cert DN<br>via usBankEPayAuthenticationAdminCertDN config]
	LoadSaifDN --> LoadSaifCert[Load SAIF admin cert<br>from LocalMachine My]
	LoadSaifCert --> SaifCheck{SAIF admin cert<br>found?}
	SaifCheck -->|No| ErrSAIF([Throw ApplicationException:<br>SAIF cert not found.])
	SaifCheck -->|Yes| Sign[Sign encrypted data<br>with SAIF private key]
	Sign --> Bundle[Bundle into AdminSingleSignOnData]
	Bundle --> End([Return AdminSingleSignOnData])
```

## Failure and edge-case behavior

- If the US Bank SSO certificate cannot be resolved from `LocalMachine\Root`, the operation throws `ApplicationException("USBank Cert not found.")` and aborts before wrapping the AES key ([BR-001](../business-rules.md#br-001-fail-fast-on-missing-signingencryption-certificates)).
- If the SAIF admin authentication certificate cannot be resolved from `LocalMachine\My`, the operation throws `ApplicationException("SAIF cert not found.")` and aborts before signing ([BR-001](../business-rules.md#br-001-fail-fast-on-missing-signingencryption-certificates)).
- If either cert-DN configuration key (`usBankEPaySSOCertDN` or `usBankEPayAuthenticationAdminCertDN`) is missing or its value is malformed JSON, `JavaScriptSerializer.Deserialize` throws inside `GetCertificateParameters`, and the corresponding certificate-load step never executes.
- The raw AES symmetric key is discarded from the local variable after RSA-wrapping and is never exposed through `AdminSingleSignOnData`'s public surface, since its property setter discards rather than stores assigned values ([BR-002](../business-rules.md#br-002-symmetric-key-material-is-not-retained-on-the-dto)).

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `Services\SAIF.Services.WebServices.Epay\WebService\USBank.vb`
- `Services\SAIF.Services.WebServices.Epay\WebService\AdminSingleSignOnData.vb`
