Skip to content

perfood/capacitor-crypto-api

Repository files navigation

@perfood/capacitor-crypto-api

This capacitor plugin provides a unified cryptographic API for secure key management and cryptographic operations using platform-specific secure hardware:

  • iOS: Secure Enclave
  • Android: StrongBox / TEE
  • Web (development): WebCrypto API

It supports generating and storing elliptic curve key pairs and using them for:

  • ECDSA: signing and verifying data
  • ECDH: key agreement (e.g. for symmetric encryption)

Secure Hardware & Cryptographic Capabilities

iOS – Secure Enclave

"Works only with NIST P-256 elliptic curve keys. These keys can only be used for creating and verifying cryptographic signatures, or for elliptic curve Diffie-Hellman key exchange (and by extension, symmetric encryption)." - Apple Developer Documentation

On iOS, the Secure Enclave imposes the following constraints:

  • Only NIST P-256 elliptic curve keys are supported
  • Supports ECDSA and ECDH
  • Private keys never leave the Secure Enclave
  • Keys can optionally be protected by biometrics

Android – StrongBox / TEE

On Android, the plugin uses StrongBox when available and falls back to the Trusted Execution Environment (TEE).

  • Supports ECDSA and ECDH
  • Hardware-backed key storage
  • Behavior depends on device manufacturer and Android version
  • Keys can optionally be protected by biometrics

Format of the signature

Secure Enclave (iOS) and StrongBox/TEE (Android) return the signature in ASN.1 DER format. The WebCrypto API returns the signature in raw (IEEE P1363) format.

This plugin has the functions derToP1363 and p1363ToDer to convert the signature from ASN.1 DER to raw (IEEE P1363) format and vice versa.

For development

For development and testing in the browser:

  • Uses the WebCrypto API
  • Key pairs are stored in the browser's localStorage
  • Supports ECDSA and ECDH

WebCrypto API is only available in secure contexts (https)

Use Cases

Two-Factor / Cryptographic Authentication (ECDSA)

This plugin can be used to implement a strong cryptographic authentication mechanism.

  1. The client generates an ECDSA key pair in secure hardware
  2. The public key is registered on the server
  3. The server sends a cryptographic challenge
  4. The client signs the challenge using the private key and sends the signed data back to the server
  5. The server verifies the signature using the stored public key

Because the private key never leaves secure hardware, this provides strong protection against key exfiltration. If the keys are protected by biometrics, the native biometrics dialog box is displayed. There is an example in the example directory.

Secure Key Exchange & Encryption (ECDH)

The plugin supports Elliptic Curve Diffie-Hellman (ECDH) to securely derive shared secrets.

Typical workflow:

  1. Client and server each have an ECDH key pair
  2. The public keys are exchanged
  3. Both sides derive the same shared secret using ECDH
  4. The derived secret is used as a symmetric key (e.g. AES)
  5. Data can now be securely:
  • Encrypted on one side
  • Decrypted on the other side

Supported use cases:

  • End-to-end encrypted communication
  • Secure storage encryption

Private keys remain protected in Secure Enclave (iOS) or StrongBox/TEE (Android).

Passkey (WebAuthn / FIDO2)

The plugin supports Passkeys for passwordless authentication using native platform dialogs.

Registration

A passkey can be created after a successful login, ensuring account ownership.

  1. Client requests registration options from the backend (WebAuthn PublicKeyCredentialCreationOptions)
  2. Backend returns challenge and relying party information
  3. Client calls registerPasskey(...)
  4. Native passkey dialog is shown (Face ID / Touch ID / Biometrics)
  5. Client returns assertion to backend
  6. Backend verifies the attestation
  7. On success: credentialId and publicKey can be stored in the user database

Authentication

  1. Client requests authentication options from backend
  2. Backend sends challenge
  3. Client calls authenticateWithPasskey(...)
  4. Native authentication dialog is shown
  5. Client returns assertion to backend
  6. Backend verifies the signature using the stored public key

Install

npm install @perfood/capacitor-crypto-api
npx cap sync

API

getECDSATags()

getECDSATags() => Promise<GetTagsResponse>

Returns all ECDSA key-pair tags that are available in the Secure Enclave (iOS) or StrongBox/TEE (Android).

Returns: Promise<GetTagsResponse>


getECDHTags()

getECDHTags() => Promise<GetTagsResponse>

Returns all ECDH key-pair tags that are available in the Secure Enclave (iOS) or StrongBox/TEE (Android).

Returns: Promise<GetTagsResponse>


generateKey(...)

generateKey(options: GenerateKeyOptions) => Promise<GenerateKeyResponse>

Generates a key-pair in the Secure Enclave (iOS) or StrongBox/TEE (Android), tags it for alter referencing and returns the public-key only, since the private-key is protected and can't be extracted. Possibility to secure private key with biometry.

Param Type
options GenerateKeyOptions

Returns: Promise<GenerateKeyResponse>

Since: 1.0.0


loadKey(...)

loadKey(options: LoadKeyOptions) => Promise<LoadKeyResponse>

Loads the public-key from the Secure Enclave (iOS) or StrongBox/TEE (Android).

Param Type
options LoadKeyOptions

Returns: Promise<LoadKeyResponse>

Since: 1.0.0


deleteKey(...)

deleteKey(options: DeleteKeyOptions) => Promise<void>

Deletes the key-pair from the Secure Enclave (iOS) or StrongBox/TEE (Android).

Param Type
options DeleteKeyOptions

Since: 1.0.0


sign(...)

sign(options: SignOptions) => Promise<SignResponse>

Signs the data in the Secure Enclave (iOS) or StrongBox/TEE (Android). Uses the private-key associated with the tag.

Only ECDSA is supported.

Param Type
options SignOptions

Returns: Promise<SignResponse>

Since: 1.0.0


verify(...)

verify(options: VerifyOptions) => Promise<VerifyResponse>

Verifies the signature of the data with the foreign public-key.

Only ECDSA is supported.

Param Type
options VerifyOptions

Returns: Promise<VerifyResponse>

Since: 1.0.0


encrypt(...)

encrypt(options: EncryptOptions) => Promise<EncryptResponse>

Encrypt data with AES-GCM.

Param Type
options EncryptOptions

Returns: Promise<EncryptResponse>


decrypt(...)

decrypt(options: DecryptOptions) => Promise<DecryptResponse>

Decrypt data with AES-GCM.

Param Type
options DecryptOptions

Returns: Promise<DecryptResponse>


isBiometricsEnabled(...)

isBiometricsEnabled(options: BiometricsEnabledOptions) => Promise<BiometricsEnabledResponse>

Is biometry enabled on the device?

Param Type
options BiometricsEnabledOptions

Returns: Promise<BiometricsEnabledResponse>


getBiometricsStatus(...)

getBiometricsStatus(options: BiometricsStatusOptions) => Promise<BiometricsStatusResponse>

Get the status of biometry on the device.

Param Type
options BiometricsStatusOptions

Returns: Promise<BiometricsStatusResponse>


getAvailableHardware()

getAvailableHardware() => Promise<AvailableHardwareResponse>

Get the list of available biometry hardware on the device.

Returns: Promise<AvailableHardwareResponse>


isDevicePasscodeSet()

isDevicePasscodeSet() => Promise<DevicePasscodeResponse>

Is the device passcode set on the device?

Returns: Promise<DevicePasscodeResponse>


hasSecureHardware()

hasSecureHardware() => Promise<SecureHardwareResponse>

Does the device have secure hardware like StrongBox?

Returns: Promise<SecureHardwareResponse>


registerPasskey(...)

registerPasskey(options: RegisterPasskeyOptions) => Promise<RegisterPasskeyResult>
Param Type
options RegisterPasskeyOptions

Returns: Promise<RegisterPasskeyResult>


authenticateWithPasskey(...)

authenticateWithPasskey(options: AuthenticateWithPasskeyOptions) => Promise<AuthenticateWithPasskeyResult>
Param Type
options AuthenticateWithPasskeyOptions

Returns: Promise<AuthenticateWithPasskeyResult>


Interfaces

GetTagsResponse

Prop Type Description
tags string[] The key-pair tags.

GenerateKeyResponse

Prop Type Description
publicKey string The public-key in base64 format.

GenerateKeyOptions

Prop Type Description
tag string The key-pair tag.
algorithm 'ecdsa' | 'ecdh' The elliptic curve algorithm
type BiometryType Biometry type if key is possibly secured with biometry.

LoadKeyResponse

Prop Type Description
publicKey string The public-key in base64 format.

LoadKeyOptions

Prop Type Description
tag string The key-pair tag.
algorithm 'ecdsa' | 'ecdh' The elliptic curve algorithm was used to create the key.

DeleteKeyOptions

Prop Type Description
tag string The key-pair tag.
algorithm 'ecdsa' | 'ecdh' The elliptic curve algorithm was used to create the key.

SignResponse

Prop Type Description
signature string The signature in base64 format.

SignOptions

Prop Type Description
tag string The key-pair tag.
data string The data to sign.
type BiometryType Biometry type if key is possibly secured with biometry.

VerifyResponse

Prop Type Description
verified boolean Whether the signature is verified.

VerifyOptions

Prop Type Description
foreignPublicKey string The foreign public-key in base64 format.
data string The signed data.
signature string The signature in base64 format.

EncryptResponse

Prop Type Description
iv string The iv in base64 format.
ciphertext string The ciphertext (encrypted data) in base64 format.

EncryptOptions

Prop Type Description
tag string The key-pair tag.
foreignPublicKey string The foreign public-key in base64 format.
plaintext string The plaintext to be encrypted.
type BiometryType Biometry type if key is possibly secured with biometry.

DecryptResponse

Prop Type Description
plaintext string The decrypted plaintext.

DecryptOptions

Prop Type Description
tag string The key-pair tag.
foreignPublicKey string The foreign public-key in base64 format.
iv string The iv in base64 format.
ciphertext string The ciphertext (encrypted data) in base64 format.
type BiometryType Biometry type if key is possibly secured with biometry.

BiometricsEnabledResponse

Prop Type Description
isEnabled boolean Whether biometry is enabled.

BiometricsEnabledOptions

Prop Type Description
type BiometryType The biometry type whose availability is to be checked.

BiometricsStatusResponse

Prop Type Description
status BiometricsStatus Status of biometry on the device.

BiometricsStatusOptions

Prop Type Description
type BiometryType The biometry type whose availability is to be checked.

AvailableHardwareResponse

Prop Type Description
hardware BiometricsHardware[] List of available biometry hardware.

DevicePasscodeResponse

Prop Type Description
isDevicePasscodeSet boolean Whether device passcode is set.

SecureHardwareResponse

Prop Type Description
hasSecureHardware boolean Whether the device has secure hardware.

RegisterPasskeyResult

Prop Type
id string
rawId string
type string
response { attestationObject: string; clientDataJSON: string; }
authenticatorAttachment string

RegisterPasskeyOptions

Prop Type
challenge string
rp { id: string; name: string; }
user { id: string; name: string; displayName: string; }
pubKeyCredParams PublicKeyCredentialParameters[]
authenticatorSelection { residentKey: 'required'; userVerification: 'preferred'; }
extensions { credProps: boolean; }

PublicKeyCredentialParameters

Prop Type
type 'public-key'
alg -7

AuthenticateWithPasskeyResult

Prop Type
id string
rawId string
type string
response { authenticatorData: string; clientDataJSON: string; signature: string; userHandle?: string; }
authenticatorAttachment string

AuthenticateWithPasskeyOptions

Prop Type
challenge string
rpId string
allowCredentials Credential[]
userVerification 'required'

Credential

Prop Type
type 'public-key'
id string

Type Aliases

BiometryType

'BIOMETRY' | 'BIOMETRY_OR_PASSCODE' | 'PASSCODE'

BiometricsStatus

'SUCCESS' | 'HARDWARE_UNAVAILABLE' | 'NONE_ENROLLED' | 'UNKNOWN'

BiometricsHardware

'FINGER' | 'IRIS' | 'FACE'

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors 2

  •  
  •