Join our Newsletter — 33% off our NHI Course
Home› Guides› Data Protection API Choices Guide: Choosing Tink, libsodium…
Guide Application Security

Data Protection API Choices Guide: Choosing Tink, libsodium or Platform Crypto Safely

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 14 min read
On this page

Most cryptographic failures in applications are not broken algorithms but correct algorithms called through the wrong API. A developer who reaches for raw AES, picks a mode, generates a nonce and stores the key next to the data has made four decisions that each can fail silently. High-level libraries such as Google Tink, libsodium and the AWS Encryption SDK exist to take those decisions away. This guide compares the main data protection APIs, explains what each one guarantees and does not, and gives a selection method, a rollout plan and review checks. It is written for application security engineers, architects and senior developers who choose or approve cryptographic dependencies.

Key takeaways

  • Choose by abstraction level, not by algorithm. A misuse-resistant API (Tink Aead, libsodium crypto_secretbox_easy, Fernet) removes nonce, mode and padding choices that low-level APIs leave to the caller.
  • Authenticated encryption is the default. OWASP ASVS 5.0 V11.3.3 expects encrypted data to be protected against modification, preferably with an approved authenticated encryption method; unauthenticated CBC or CTR is a finding.
  • The key is the hard part. Every library in this guide is only as safe as where its key lives. Tink and the AWS Encryption SDK integrate with a KMS; libsodium and Fernet leave key storage entirely to you.
  • Know each API's limits. Random-nonce AES-GCM is limited to about 2^32 messages per key, Fernet loads whole messages into memory, and sealed boxes do not authenticate the sender.
  • Standardise and inventory. One approved library per language, wrapped in an internal module, is easier to review, migrate and make crypto-agile than many teams each calling primitives directly.

Why API level matters more than algorithm choice

Low-level interfaces such as the Java Cryptography Architecture Cipher class, the Web Crypto SubtleCrypto interface and OpenSSL's EVP functions expose primitives. They are flexible and necessary for protocol implementers, but they let callers pick insecure combinations. MDN's documentation of SubtleCrypto warns that its low-level primitives are very easy to misuse and that the pitfalls can be very subtle. The OWASP Cryptographic Storage Cheat Sheet makes the same point from the other side: IVs and similar attributes should be handled automatically by the library, custom algorithms should never be written, and ECB should not be used outside very specific circumstances.

A misuse-resistant library changes the developer's job from "assemble a construction" to "call encrypt with a key handle". Tink's own design notes describe its Aead interface as generating a fresh random nonce on every encrypt call and not accepting a caller-supplied nonce, which removes nonce reuse as a class of bug. libsodium's crypto_secretbox_easy still takes a nonce but fixes the algorithm, the tag and the layout, and its documentation states plainly that a nonce should never be reused with the same key. The difference in review effort is large: a reviewer checking a Tink call needs to look at key handling and associated data; a reviewer checking a raw AES call needs to check mode, padding, IV generation, tag verification, constant-time comparison and error handling.

For the underlying theory of modes and nonce misuse, see the Authenticated Encryption and Block Cipher Modes Guide and the Cryptographic Protocol Failures and Misuse Guide. This page stays on the practical question of which API to put in front of developers.

The main high-level libraries compared

LibraryLanguagesWhat it abstractsKey managementWatch for
Google TinkC++, Java, Go, Python, Objective-C (support varies per key type)Primitives by use case: AEAD, Streaming AEAD, Deterministic AEAD, MAC, PRF, signatures, hybrid encryption, JWTKeysets with a primary key; encrypted keysets wrapped by a KMS key (gcp-kms://, aws-kms://, hcvault:// in Go)Cleartext keysets are possible but discouraged; some key types need Conscrypt in Java
libsodiumC, with bindings for most languages; JavaScript and WebAssembly buildsFixed constructions: secretbox, AEAD, secretstream, box and sealed box, signatures, key exchange, Argon2id password hashingNone: raw key bytes are the caller's responsibilityCaller supplies nonces for secretbox and AEAD; AES256-GCM requires hardware support
AWS Encryption SDKC, C#/.NET, Java, JavaScript, Python, Rust, Go, CLIEnvelope encryption with a unique data key per object and a defined message formatKeyrings or master key providers wrapping data keys under KMS or other wrapping keysNot interoperable with other libraries' formats; symmetric KMS keys only
pyca/cryptography FernetPythonAuthenticated symmetric tokens (AES-128-CBC with HMAC-SHA256, random IV)Single 32-byte URL-safe base64 key; MultiFernet for rotationTimestamp stored in plaintext; whole message in memory; not for large files
Platform AEAD APIs (Go crypto/cipher, .NET AesGcm, Java JCA, Web Crypto)One language eachA single primitive with a safer shape than raw block ciphersPlatform key stores or noneCaller still chooses nonce strategy, tag size and key storage

What the platform APIs now do for you

  • Go: cipher.NewGCMWithRandomNonce generates a random 96-bit nonce, prepends it to the ciphertext in Seal and extracts it in Open. The Go source states that a key must not encrypt more than 2^32 messages with it, to keep random nonce collisions negligible.
  • .NET: the AesGcm constructors that do not take a tag size are marked obsolete (diagnostic SYSLIB0053); use the constructor that fixes tagSizeInBytes so encryption and decryption agree on a full-length tag.
  • Java: always name the full transformation (for example AES/GCM/NoPadding). A bare "AES" string leaves the mode and padding to the provider default, which in common providers is ECB.
  • Browser: SubtleCrypto is only available in secure contexts. exportKey exports keys unencrypted; use wrapKey for sensitive keys and create keys as non-extractable where the design allows.

Choosing the right primitive for the job

Most selection mistakes come from using encryption where a MAC or signature is needed, or from using deterministic encryption without understanding what it leaks. Tink organises its API by use case, which is a useful checklist even outside Tink.

NeedPrimitiveTinklibsodiumNotes
Encrypt records or fieldsAEADAead (AES-GCM, XChaCha20-Poly1305 and others)crypto_aead_xchacha20poly1305_ietf_* or crypto_secretbox_easyBind context (tenant ID, record ID) as associated data
Encrypt large files or streamsStreaming AEADStreamingAead (AES-GCM-HKDF-STREAMING)crypto_secretstream_xchacha20poly1305_*Detects truncation and reordering; avoids loading whole files
Searchable or deduplicated encrypted valuesDeterministic AEADDeterministicAead (AES-SIV)No direct equivalentEqual plaintexts give equal ciphertexts: leaks equality by design
Integrity only, both parties share a keyMACMac (HMAC-SHA2, AES-CMAC)crypto_authVerify with the library's constant-time check, never string comparison
Integrity verifiable by anyoneSignaturePublicKeySign / PublicKeyVerify (ECDSA, Ed25519, ML-DSA, SLH-DSA)crypto_sign (Ed25519)Post-quantum signature key types are available in Tink for some languages
Encrypt to a public keyHybrid encryptionHybridEncrypt (HPKE, ECIES)crypto_box_sealNeither authenticates the sender; add a signature if the sender matters
PasswordsPassword hashingNot in Tinkcrypto_pwhash_str (Argon2id default since 1.0.15)See the Password Hashing and Key Derivation Guide
Data under a cloud KMS key at scaleEnvelope encryptionKMS Envelope AEADBuild it yourselfOne KMS call per operation; consider caching or a KMS-encrypted keyset

OWASP's cheat sheet recommends an established hybrid scheme such as HPKE (RFC 9180) for public-key encryption and notes that the HPKE base mode does not authenticate the sender and gives only limited replay protection. libsodium's sealed box documentation makes the same point: the recipient can verify integrity but not the sender's identity.

Keys, keysets and KMS integration

A high-level library prevents construction errors; it does not decide where keys live. This is where the identity angle is real: data encryption keys and the credentials that unwrap them are non-human secrets, and a hard-coded key is a credential leak with a cryptographic blast radius.

  • Tink keysets: Tink stores keys in keysets, generated from key templates (for example AES128_GCM) and serialised encrypted under a key encryption key held in a KMS. Tink's documentation recommends encrypted keysets and warns that cleartext keysets are not recommended because keys stored in plaintext often leak. The Tinkey CLI can create KMS-wrapped keysets.
  • Envelope encryption: Tink's KMS Envelope AEAD and the AWS Encryption SDK both generate a fresh data key per message and wrap it under a KMS key. The AWS SDK stores encrypted data keys with the ciphertext in its message format and can wrap one data key under several wrapping keys, for example a KMS key and an on-premises HSM key. See the AWS KMS Security Guide and the Cloud KMS and Cloud HSM Guide.
  • libsodium and Fernet: both take raw key bytes. Load them from a secrets manager or KMS at start-up, never from source code or a configuration file in the repository. libsodium provides sodium_memzero, sodium_mlock and sodium_malloc for keeping keys out of swap and core dumps, and its documentation recommends disabling core dumps for crypto code in production.
  • Rotation: Tink keysets hold several keys with one primary used for new encryptions; MultiFernet encrypts with the first key and tries each key on decryption, and its rotate() re-encrypts a token under the primary key. Tink's key management overview suggests enabling automatic rotation of the KMS key.
  • The KMS credential: the workload identity that can call KMS decrypt is the real key. Scope it to the specific key and the specific service. See the Cryptographic Key Management Guide.

Decision guidance

SituationReasonable defaultWhy
Cloud-hosted service in Java, Go, Python or C++, data at restTink with KMS-encrypted keysets, or the cloud provider's encryption SDKKey handling, rotation and envelope encryption are built in
Polyglot estate needing one ciphertext format across languagesAWS Encryption SDK (interoperable across its languages) or TinkA defined message format decrypts in any supported language
Embedded, mobile or C code without a KMSlibsodiumSmall, portable, fixed constructions; pair with the platform key store
Python application encrypting small tokens or fieldsFernet with MultiFernetSimple, authenticated, rotation built in; not for large files
Regulated workload needing FIPS 140-3 validated modulesPlatform APIs backed by a validated module, or a library built on oneHigh-level libraries are not themselves validated modules; check the build. See the FIPS 140-3 and Cryptographic Module Validation Guide
Browser-side encryptionWeb Crypto AES-GCM with non-extractable keys, or libsodium's JavaScript buildKeep keys in CryptoKey objects; never ship long-term keys in JavaScript

Small organisations: pick one library per language, publish a short code snippet for each approved use, and block direct primitive use in code review. Large organisations: wrap the chosen library in an internal crypto module owned by a platform team, so algorithm changes (for example a post-quantum migration) happen in one place. That wrapper is what OWASP ASVS V11.2.2 means by designing for crypto agility. See the Crypto-Agility Guide.

Rolling out an approved crypto library

  1. Inventory current use. Search code for direct primitive calls (Cipher.getInstance, createCipheriv, crypto.subtle, AES.new, EVP_Encrypt) and hard-coded key material. ASVS V11.1.2 and V11.1.3 expect a maintained inventory and discovery. See the Cryptographic Inventory and CBOM Guide.
  2. Publish the approved list. One library and a small set of key templates per language and use case, with examples. Record the decision so reviewers can cite it.
  3. Build the wrapper. Expose encrypt(plaintext, context) and decrypt(ciphertext, context); take keys only from the KMS or secrets manager; include a key or format version so old ciphertext stays readable.
  4. Test against known-answer and attack vectors. Project Wycheproof publishes JSON test vectors for AES-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305, ECDSA, EdDSA, RSA, HKDF, ML-KEM and more; run them in CI for any wrapper that exposes primitives.
  5. Pilot on one service. Encrypt new writes with the new library while reading old ciphertext with the legacy path (dual read). Keep the legacy decrypt path until re-encryption completes.
  6. Re-encrypt and retire. Batch re-encrypt historical data, track progress as a metric, then remove the legacy decrypt code and its keys.
  7. Enforce. Add static analysis rules that flag direct primitive use outside the wrapper, and fail builds on hard-coded keys.

Rollback: because new ciphertext carries a version marker and the legacy path is kept during the pilot, rolling back means switching writes back to the old path; never delete old keys until every record encrypted under them has been re-encrypted and verified.

Detection and measurement

  • Static analysis: rules for ECB, static or zero IVs, Math.random() or java.util.Random for keys or nonces (OWASP lists the CSPRNG replacements per language), and string equality on MACs.
  • Secret scanning: detect key material and Tink cleartext keysets committed to repositories. See the Git Secret Scanning Guide.
  • KMS audit logs: decrypt calls by principal and key; alert on new principals or unusual volume against data keys.
  • Dependency monitoring: track library versions and advisories; libsodium, Tink and pyca/cryptography all publish releases that change defaults.

Metrics that show the programme is working:

  • Percentage of services whose encryption goes through the approved wrapper.
  • Count of direct primitive call sites outside the wrapper, trending to zero.
  • Hard-coded key findings open, and mean time to remove and rotate them.
  • Percentage of stored ciphertext under a current key version.
  • Percentage of data keys wrapped by a KMS or HSM rather than stored in configuration.

Framework mapping

FrameworkReferenceRelevance
OWASP ASVS 5.0V11.2.1, V11.2.2, V11.3.1 to V11.3.4, V11.5.1Validated implementations, crypto agility, no ECB, authenticated encryption, nonce uniqueness, CSPRNG
NIST SP 800-53 Rev. 5SC-12, SC-13, SC-28, SA-8, SA-15Key management, cryptographic protection, data at rest, engineering principles, development standards
NIST CSF 2.0PR.DS-01, PR.DS-02Data at rest and in transit protection
ISO/IEC 27001:2022Annex A 8.24 Use of cryptographyRules for cryptography and key management
CIS Controls v8.13.11 Encrypt Sensitive Data at RestEncryption of sensitive data stores
MITRE ATT&CKT1552.001 Credentials In Files; T1600 Weaken EncryptionKeys left in files and configuration; attacker downgrading encryption

Common failure patterns

  • Hard-coded keys shared by every installation: in the Gladinet hard-coded keys exploitation, the AES key and IV used for access tickets were derived from fixed strings, so one extraction let attackers forge tickets against every customer. A KMS-wrapped keyset generated per installation would have removed the shared secret.
  • Encryption without authentication: AES-CBC or CTR with no MAC, often from a copied snippet. Ciphertext can be modified, and padding errors can become an oracle. ASVS V11.3.3 and V11.3.5 address this.
  • Nonce reuse at scale: counters reset on restart, or random 96-bit nonces under one key beyond the roughly 2^32 message limit that libsodium and Go both document for AES-GCM. Use XChaCha20-Poly1305, Tink's random-nonce Aead, or rekey.
  • Wrong primitive: sealed boxes or HPKE base mode used as if they proved who sent the message, or deterministic encryption used for high-sensitivity fields where equality leakage matters.
  • Cleartext keysets and exported keys: Tink cleartext keysets in configuration, or Web Crypto keys exported unencrypted to local storage.
  • Library sprawl: five libraries across ten teams, none inventoried, so a deprecation or post-quantum migration cannot be planned.

Practitioner checklist

  • Publish one approved data protection library per language, with key templates and examples for each use case.
  • Require authenticated encryption everywhere; treat unauthenticated modes and ECB as blocking findings.
  • Bind context such as tenant and record identifiers as associated data.
  • Keep data keys wrapped by a KMS or HSM; ban cleartext keysets and hard-coded keys.
  • Scope the KMS decrypt permission to the specific workload identity and key.
  • Use streaming AEAD for large files and respect per-key message limits.
  • Wrap the library in an internal module with a version marker to support rotation and crypto agility.
  • Run Wycheproof vectors in CI for any code that exposes primitives.
  • Track direct primitive call sites and hard-coded key findings as metrics.

Standards and references

Related NHI Mgmt Group resources: Cryptographic Key Management Guide · Authenticated Encryption and Block Cipher Modes Guide · OWASP CI/CD Top 10 CICD-SEC-6 Insufficient Credential Hygiene Guide · Crypto-Agility Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.