cloak.business

Asymmetric Encryption (Public-Key Encryption)

Last Updated: 2026-03-06


Overview#

Asymmetric Encryption is a multi-party encryption feature that uses RSA-4096 key pairs for secure data sharing. Unlike symmetric encryption (where the same key encrypts and decrypts), asymmetric encryption uses two separate keys:

  • Public key — used by anyone to encrypt data for you
  • Private key — used only by you to decrypt that data

This is designed for workflows where external applications or third parties need to encrypt PII before sending it to you, and only you can decrypt it.

Asymmetric encryption is completely separate from the existing symmetric encryption feature. Both can be used independently or together in the same workflow.


Table of Contents#

  1. How It Works
  2. Key Pair Management
  3. Encrypting Data
  4. Decrypting Data
  5. Multi-Party Use Cases
  6. API Usage
  7. Security Architecture
  8. Comparison: Symmetric vs Asymmetric
  9. FAQ

How It Works#

Asymmetric encryption uses a hybrid scheme combining RSA-4096 and AES-256-GCM:

Encryption (encrypt_asym)#

For each PII entity detected in your text:

  1. A random 32-byte AES session key is generated
  2. The session key is encrypted with the recipient's RSA-4096 public key (RSA-OAEP with SHA-256)
  3. The plaintext is encrypted with the session key (AES-256-GCM)
  4. The encrypted session key (512 bytes), nonce (12 bytes), and ciphertext are concatenated and base64-encoded

Output size: ~730 characters per encrypted entity (base64-encoded)

Decryption (decrypt_asym)#

  1. The base64 string is decoded
  2. The encrypted session key is extracted (first 512 bytes) and decrypted with the private key (RSA-OAEP)
  3. The AES nonce and ciphertext are extracted
  4. The plaintext is restored using AES-256-GCM decryption

The decrypted text is an exact character-for-character match of the original.


Key Pair Management#

Generating a Key Pair#

  1. Go to Settings > Asymmetric Keys in your dashboard
  2. Enter a name for your key pair (e.g., "Production API Keys", "Partner Integration")
  3. Click Generate RSA-4096 Key Pair
  4. The key pair is generated in your browser using WebCrypto (the private key never leaves your device during generation)
  5. Both keys are uploaded to your profile — the private key is encrypted server-side before storage

Viewing Your Keys#

Each key pair card shows:

  • Key name and algorithm (RSA-4096)
  • Fingerprint — SHA-256 hash of the public key for identification
  • Status — Active or Inactive
  • Usage count and last used timestamp

Expand a key pair to see:

  • Public Key (For Encryption) — The PEM-formatted public key. Share this with external apps or partners who need to encrypt data for you.
  • Private Key (For Decryption — Keep Secret) — The PEM-formatted private key. This is used only by you to decrypt data.

Both keys can be copied to clipboard or downloaded as .pem files.

Key Pair Operations#

OperationDescription
Activate/DeactivateDeactivated keys cannot be used for new encryption. Already-encrypted data can still be decrypted.
RenameChange the key pair name (must be unique per account)
DeletePermanently remove the key pair. This is irreversible — any data encrypted with this key pair's public key cannot be decrypted after deletion.

Encrypting Data#

Via the Web Interface#

  1. Paste or type your text in the Anonymizer
  2. Click Analyze to detect PII entities
  3. For each entity type you want to encrypt, select Encrypt (Asymmetric) as the anonymization method
  4. Choose which key pair to use (by name or ID)
  5. Click Anonymize — encrypted entities appear as base64 strings in the output

Via the API#

Encryption is a two-step process:

Step 1: Analyze — Detect PII entities in the text

curl -X POST https://cloak.business/api/presidio/analyze \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "My email is john@example.com and phone is +1-202-555-0147.",
    "language": "en"
  }'

Response:

{
  "results": [
    {"entity_type": "EMAIL_ADDRESS", "start": 12, "end": 28, "score": 1.0},
    {"entity_type": "PHONE_NUMBER", "start": 43, "end": 59, "score": 0.75}
  ]
}

Step 2: Anonymize — Encrypt the detected entities

curl -X POST https://cloak.business/api/presidio/anonymize \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "My email is john@example.com and phone is +1-202-555-0147.",
    "analyzer_results": [
      {"entity_type": "EMAIL_ADDRESS", "start": 12, "end": 28, "score": 1.0},
      {"entity_type": "PHONE_NUMBER", "start": 43, "end": 59, "score": 0.75}
    ],
    "operators": {
      "DEFAULT": {"type": "encrypt_asym", "public_key_id": "YOUR_KEY_PAIR_ID"}
    }
  }'

Response:

{
  "text": "My email is GIszLbhC+eP04L7Z...== and phone is TKm1qial5As...==.",
  "items": [
    {"start": 12, "end": 742, "entity_type": "EMAIL_ADDRESS", "operator": "encrypt_asym"},
    {"start": 757, "end": 1487, "entity_type": "PHONE_NUMBER", "operator": "encrypt_asym"}
  ]
}

Operator Options#

You can specify the public key in two ways:

ParameterDescription
public_key_idYour key pair ID — the server resolves it to the public key PEM. The key pair must be active.
public_keyInline PEM-formatted public key string. Use this when the external app already has the public key.

Using public_key_id is recommended for internal use. Using public_key (inline PEM) is useful when external apps handle key distribution themselves.

Mixed Operators#

You can combine encrypt_asym with other anonymization methods in the same request:

{
  "operators": {
    "EMAIL_ADDRESS": {"type": "encrypt_asym", "public_key_id": "abc123"},
    "PERSON": {"type": "replace", "new_value": "[REDACTED]"},
    "US_SSN": {"type": "mask", "masking_char": "*", "chars_to_mask": 5, "from_end": false}
  }
}

Decrypting Data#

Via the API#

Decryption uses the deanonymize endpoint with the decrypt_asym operator and your private key:

curl -X POST https://cloak.business/api/presidio/deanonymize \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "My email is GIszLbhC+eP04L7Z...== and phone is TKm1qial5As...==.",
    "anonymizer_results": [
      {"start": 12, "end": 742, "entity_type": "EMAIL_ADDRESS", "operator": "encrypt_asym"},
      {"start": 757, "end": 1487, "entity_type": "PHONE_NUMBER", "operator": "encrypt_asym"}
    ],
    "deanonymizers": {
      "DEFAULT": {"type": "decrypt_asym", "private_key": "-----BEGIN RSA PRIVATE KEY-----\n...your private key PEM...\n-----END RSA PRIVATE KEY-----"}
    }
  }'

Response:

{
  "text": "My email is john@example.com and phone is +1-202-555-0147."
}

Important Notes#

  • The anonymizer_results must exactly match the positions in the encrypted text. Save the items array from the anonymize response.
  • The private key must be the exact PEM that corresponds to the public key used for encryption.
  • Using the wrong private key returns HTTP 400 with the message: "Decryption failed. The encryption key may be incorrect or the data format is invalid."
  • Using a public key for decryption also fails with the same error — you must use the private key.

Multi-Party Use Cases#

External App Integration#

  1. You create an asymmetric key pair in your cloak.business account
  2. You share your public key (or key pair ID) with the external app
  3. The external app calls the cloak.business API to encrypt PII using your public key
  4. The external app sends you the encrypted output
  5. Only you can decrypt it using your private key

Data Processing Pipeline#

  1. Create a key pair named "Pipeline Encryption"
  2. Configure your data pipeline to use encrypt_asym with the public_key_id
  3. Data flows through the pipeline with PII encrypted
  4. When you need the original data, call the deanonymize endpoint with your private key

Third-Party Audit#

  1. Share your public key PEM with the auditor
  2. The auditor encrypts sensitive findings using your public key
  3. The auditor sends you the encrypted report
  4. You decrypt it — no sensitive data was exposed during transmission

API Usage#

Key Management Endpoints#

List Key Pairs

GET /api/asymmetric-keys
Authorization: Bearer YOUR_API_KEY

Returns all key pairs for the authenticated user (metadata only, no private keys).

{
  "keyPairs": [
    {
      "id": "cmmf6ow61001ofnssf739is4f",
      "keyName": "Production Keys",
      "fingerprint": "5fe079d73ba8d5d3...",
      "algorithm": "RSA-4096",
      "isActive": true,
      "isZKWrapped": false,
      "hasPrivateKeyBackup": false,
      "usageCount": 42,
      "lastUsedAt": "2026-03-06T17:43:12.000Z",
      "createdAt": "2026-03-06T17:00:00.000Z",
      "updatedAt": "2026-03-06T17:43:12.000Z"
    }
  ]
}

Create Key Pair

POST /api/asymmetric-keys
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "keyName": "My Key Pair",
  "publicKeyPem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----",
  "privateKeyPem": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
}

The private key is encrypted server-side before storage and never stored in plaintext.

Get Key Pair Metadata

GET /api/asymmetric-keys/{id}

Returns metadata without the private key.

Get Key Pair with Private Key

GET /api/asymmetric-keys/{id}?includePrivateKey=true

Returns metadata plus the decrypted private key PEM. Use this when you need the private key for decryption.

Get Public Key Only

GET /api/asymmetric-keys/{id}/public

Returns only the public key PEM. Use this to share with external apps.

Update Key Pair

PUT /api/asymmetric-keys/{id}
Content-Type: application/json

{"keyName": "New Name"}

or

{"isActive": false}

Delete Key Pair

DELETE /api/asymmetric-keys/{id}

Permanently deletes the key pair. Irreversible.

Encryption/Decryption Endpoints#

See Encrypting Data and Decrypting Data above. The endpoints are:

  • POST /api/presidio/analyze — Detect PII entities
  • POST /api/presidio/anonymize — Encrypt entities (with encrypt_asym operator)
  • POST /api/presidio/deanonymize — Decrypt entities (with decrypt_asym operator)

Security Architecture#

Private Key Protection#

  • Private keys are encrypted at rest using AES-256-GCM with per-user context
  • Encryption/decryption uses the encryptUserKey()/decryptUserKey() functions from the symmetric key service
  • For Zero-Knowledge (ZK) users, private keys can be additionally wrapped with the user's Key Encryption Key (KEK)
  • Private keys are never logged, never included in error messages, and never exposed in metadata responses

Public Key Transparency#

  • Public keys are stored as plaintext PEM — they are public by design
  • The SHA-256 fingerprint provides a compact identifier for verification
  • Public keys can be freely shared with external parties

Audit Logging#

Every key operation is logged to the audit trail:

ActionWhen
asym_key_createKey pair created
asym_key_accessPublic or private key retrieved
asym_key_updateKey pair renamed or activated/deactivated
asym_key_deleteKey pair deleted
asym_key_resolvePublic key resolved for encrypt_asym operator

Session Validation#

Deleting a key pair requires session validation for ZK users (via x-session-key-hash header).


Comparison: Symmetric vs Asymmetric#

AspectSymmetric (encrypt)Asymmetric (encrypt_asym)
Key typeSingle shared key (16/24/32 chars)RSA-4096 key pair (public + private)
EncryptionAES-256-GCM (Fernet)Hybrid RSA-OAEP + AES-256-GCM
Output size~88 chars per entity~730 chars per entity
Who can encryptAnyone with the keyAnyone with the public key
Who can decryptAnyone with the keyOnly the private key holder
Multi-partyKey must be shared (security risk)Only public key shared (safe)
Use caseInternal encrypt/decrypt workflowsExternal apps encrypting data for you
Operator nameencrypt / decryptencrypt_asym / decrypt_asym
Key parameterkey (string)public_key_id or public_key / private_key
Token costStandardStandard (same pricing)

FAQ#

Can I use both symmetric and asymmetric encryption together?#

Yes. In a single anonymization request, you can use encrypt for some entity types and encrypt_asym for others. They are independent features.

What happens if I delete a key pair?#

Deletion is permanent and irreversible. Any data that was encrypted with the deleted key pair's public key cannot be decrypted. Save the anonymizer_results and private key before deleting if you still need to decrypt existing data.

Can I decrypt with the public key?#

No. Attempting to use a public key for decryption returns HTTP 400: "Decryption failed. The encryption key may be incorrect or the data format is invalid." Only the matching private key can decrypt.

What happens if I use the wrong private key?#

The API returns HTTP 400 with the same error message as above. RSA-OAEP decryption fails cryptographically — no partial data is exposed.

Can I use an inline public key PEM instead of a key pair ID?#

Yes. Pass "public_key": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----" in the operator instead of "public_key_id". This is useful when external apps manage their own key distribution.

What is the output size of encrypted entities?#

Each encrypted entity produces approximately 730 base64 characters, regardless of the original entity length. This is due to the 512-byte RSA-encrypted session key plus AES-GCM overhead.

Does deactivating a key pair affect existing encrypted data?#

Deactivating a key pair prevents new encryption operations using that key pair ID. Already-encrypted data can still be decrypted using the private key (retrieved via ?includePrivateKey=true before deactivation, or reactivate the key pair).

How is the private key stored?#

The private key is encrypted server-side using AES-256-GCM with per-user context before storage. It is never stored in plaintext. When retrieved via the API with ?includePrivateKey=true, it is decrypted server-side and returned over HTTPS.

What algorithm is used?#

RSA-4096 with OAEP padding (SHA-256 for both hash and MGF1) for key encapsulation, and AES-256-GCM for data encryption. This is a standard hybrid encryption scheme used in TLS, S/MIME, and PGP.

Is there a token cost difference?#

No. Asymmetric encryption costs the same number of tokens as any other anonymization operator (replace, redact, mask, hash, symmetric encrypt). Token cost depends on text length and number of entities, not the operator type.

Can I use asymmetric encryption from the Desktop App?#

The Desktop App currently uses the existing symmetric encryption feature. Asymmetric encryption is available via the web interface and API.

How do I share my public key with an external app?#

  1. Go to Settings > Asymmetric Keys
  2. Expand your key pair
  3. Copy the public key PEM or download it as a .pem file
  4. Share the PEM file or key pair ID with the external app

Alternatively, the external app can call GET /api/asymmetric-keys/{id}/public with a valid Bearer token to retrieve the public key programmatically.