PHPackages                             poly-crypto/poly-crypto - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. poly-crypto/poly-crypto

ActiveLibrary[Security](/categories/security)

poly-crypto/poly-crypto
=======================

High-level cryptographic functions that are interoperable between NodeJS and PHP 7.1+

2.0.6(3y ago)127.8k↓100%3[1 PRs](https://github.com/kensnyder/poly-crypto/pulls)ISCTypeScriptPHP &gt;=7.1.0CI failing

Since Apr 7Pushed 1y ago2 watchersCompare

[ Source](https://github.com/kensnyder/poly-crypto)[ Packagist](https://packagist.org/packages/poly-crypto/poly-crypto)[ Docs](https://github.com/kensnyder/poly-crypto)[ RSS](/packages/poly-crypto-poly-crypto/feed)WikiDiscussions main Synced today

READMEChangelog (6)Dependencies (1)Versions (10)Used By (0)

poly-crypto
===========

[](#poly-crypto)

**Poly**glot **Crypto**graphy. High-level cryptographic functions that are interoperable between NodeJS and PHP 7.2+ (and 8.0+).

[![NPM Link](https://camo.githubusercontent.com/372c861640f2442faf5b7c5a402234ad9e960f5bfbeadd094510c0f7cb6662fe/68747470733a2f2f62616467656e2e6e65742f6e706d2f762f706f6c792d63727970746f3f763d322e332e30)](https://npmjs.com/package/poly-crypto)[![Packagist Link](https://camo.githubusercontent.com/2cb198223e08888fa33ec04f2c18f09f7524383d9742802cfd3f461cf03f616d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f706f6c792d63727970746f2f706f6c792d63727970746f2f322e312e30)](https://packagist.org/packages/poly-crypto/poly-crypto)[![Language](https://camo.githubusercontent.com/84ab2b10bc492c0d668897da1ca15df9d1d39b519a38fa34a751b3c426796ebc/68747470733a2f2f62616467656e2e6e65742f7374617469632f6c616e67756167652f54533f763d322e332e30)](https://github.com/search?q=repo:kensnyder/poly-crypto++language:TypeScript&type=code)[![Build Status](https://github.com/kensnyder/poly-crypto/actions/workflows/workflow.yml/badge.svg?v=2.3.0)](https://github.com/kensnyder/poly-crypto/actions)[![Code Coverage](https://camo.githubusercontent.com/da1d6e73b484f442ac399ab059b4c3a469328a7141714bfaf64a8feb3f3f046a/68747470733a2f2f636f6465636f762e696f2f67682f6b656e736e796465722f706f6c792d63727970746f2f6272616e63682f6d61696e2f67726170682f62616467652e7376673f763d322e332e30)](https://codecov.io/gh/kensnyder/poly-crypto)[![Gzipped Size](https://camo.githubusercontent.com/bf5e378254aa267e5b9d8c91267963de869dad23e38e4b92af0fae060f7054a6/68747470733a2f2f62616467656e2e6e65742f62756e646c6570686f6269612f6d696e7a69702f706f6c792d63727970746f3f6c6162656c3d6d696e7a697070656426763d322e332e30)](https://bundlephobia.com/package/poly-crypto@2.3.0)[![Dependency details](https://camo.githubusercontent.com/17d54970f513aed7c91abceabe9a32ffaa008863e1fc1ae429788ee997c663da/68747470733a2f2f62616467656e2e6e65742f62756e646c6570686f6269612f646570656e64656e63792d636f756e742f706f6c792d63727970746f3f763d322e332e30)](https://www.npmjs.com/package/poly-crypto?activeTab=dependencies)[![Tree shakeable](https://camo.githubusercontent.com/caf1411b7fd2b7330a1695349b43afa903e3b79fb00dd2549cc90bed1d97bb28/68747470733a2f2f62616467656e2e6e65742f62756e646c6570686f6269612f747265652d7368616b696e672f706f6c792d63727970746f3f763d322e332e30)](https://www.npmjs.com/package/poly-crypto)[![ISC License](https://camo.githubusercontent.com/113f8b00471f6346a9511be351f93919cf0652054bdedcc45e3e6432391de613/68747470733a2f2f62616467656e2e6e65742f6769746875622f6c6963656e73652f6b656e736e796465722f706f6c792d63727970746f3f763d322e332e30)](https://opensource.org/licenses/ISC)

Project Goals
-------------

[](#project-goals)

1. APIs that work exactly the same on NodeJS and PHP 7.2+ (and 8.0+)
2. Package for Node that can be used on serverless functions without external C bindings
3. Two-way symmetric encryption with a key or with password and salt
4. Password hashing
5. Support ESM with tree shaking; support CommonJS; Written in TypeScript

Installation
------------

[](#installation)

You can use PolyCrypto in JavaScript, PHP, or both.

```
# NodeJS
npm install poly-crypto

# PHP
composer require poly-crypto/poly-crypto
```

Cheatsheet
----------

[](#cheatsheet)

SectionNodeJSPHP[Encrypt with key](#encrypt-and-decrypt-with-key)PolyAES.withKey(key).encrypt(data)PolyAES::withKey($key)-&gt;encrypt($data)[Decrypt with key](#encrypt-and-decrypt-with-key)PolyAES.withKey(key).decrypt(encrypted)PolyAES::withKey($key)-&gt;decrypt($encrypted)[Encrypt with password](#encrypt-and-decrypt-with-password)PolyAES.withPassword(password, salt).encrypt(data)PolyAES::withPassword($password, $salt)-&gt;encrypt($data)[Decrypt with password](#encrypt-and-decrypt-with-password)PolyAES.withPassword(password, salt).decrypt(encrypted)PolyAES::withPassword($password, $salt)-&gt;decrypt($encrypted)[Bcrypt hash](#password-hashing)PolyBcrypt.hash(password)PolyBcrypt::hash($password)[Bcrypt verify](#password-hashing)PolyBcrypt.verify(password, hash)PolyBcrypt::verify($password, $hash)[Digest functions](#digest-functions)PolyDigest.sha256(data)PolyDigest::sha256($data)[Random functions](#random-functions)PolyRand.slug(length)PolyRand::slug($length)[Base conversion](#base-conversion)PolyConvert.base(digits, fromBase, toBase)PolyRand::base($digits, $fromBase, $toBase)Table of Contents
-----------------

[](#table-of-contents)

- [poly-crypto](#poly-crypto)
    - [Project Goals](#project-goals)
    - [Installation](#installation)
    - [Cheatsheet](#cheatsheet)
    - [Table of Contents](#table-of-contents)
    - [Technology choices](#technology-choices)
        - [AES-256 GCM](#aes-256-gcm)
        - [Bcrypt](#bcrypt)
        - [Randomness](#randomness)
    - [Use cases](#use-cases)
    - [Misuse](#misuse)
        - [AES Encryption](#aes-encryption)
            - [Encrypt and decrypt with key](#encrypt-and-decrypt-with-key)
            - [Encrypt and decrypt with password](#encrypt-and-decrypt-with-password)
        - [Password hashing](#password-hashing)
        - [Digest functions](#digest-functions)
        - [Random functions](#random-functions)
        - [Base conversion](#base-conversion)
    - [Command line utilities](#command-line-utilities)
        - [Global install of poly-crypto](#global-install-of-poly-crypto)
    - [Browser usage](#browser-usage)
    - [JavaScript direct import](#javascript-direct-import)
    - [Unit tests](#unit-tests)
    - [Contributing](#contributing)
    - [License](#license)

Technology choices
------------------

[](#technology-choices)

### AES-256 GCM

[](#aes-256-gcm)

As of December 2022, AES-256 Encryption with GCM block mode is a reputable and secure method that is available across PHP and NodeJS without any extensions. With the right arguments and options, these 2 languages can decrypt one another's encrypted strings using PHP's openssl\_\* functions and npm's node-forge.

### Bcrypt

[](#bcrypt)

As of January 2025, Bcrypt password hashing is reputable and secure. These 2 languages can hash and verify one another's hashes: npm's bcrypt-js and PHP's password\_hash function.

### Randomness

[](#randomness)

Cryptographic randomness is tricky. These 2 languages can provide secure randomness: PHP's random\_bytes() and Node's crypto.randomBytes() functions.

Use cases
---------

[](#use-cases)

poly-crypto's basic use cases:

CaseInputOutputNodeJS1.Encrypt data that you can to decrypt laterEncryption key stringbase-64 encoded stringPolyAES.withKey(hexKey).encrypt(data)2.Encrypt data for a user that he or she can decrypt laterUser-supplied password &amp; system saltbase-64 encoded stringPolyAES.withPassword(password, salt).encrypt(data)3.Hash passwords with bcryptPassword stringbcrypt hashPolyBcrypt.hash(password)4.Check if a password matches the given bcrypt hashPassword string &amp; bcrypt hashTrue if password matchesPolyBcrypt.verify(password, hash)5.Calculate digests (e.g. sha256)String datadigest stringPolyDigest.sha256(data)6.Generate random slugsnumber of charactersa string with random charactersPolyRand.slug(numCharacters)7.Convert numbers between basesnumber to convertconverted numberPolyConvert.base(input, from, to)Misuse
------

[](#misuse)

1. **File encryption.** poly-crypto modules are not meant to be used to encrypt entire files. You'll want to use a C-based library that is designed to encrypt large amounts of data quickly. For example, consider the following:
    1. poly-crypto is not fast for large files.
    2. AES-256 GCM encryption can be parallelized in languages that support threading for faster processing
2. **Streaming data.** PolyAES is not designed to encrypt streaming data.
3. **Secure key storage.** If you store encryption keys or user passwords in plain text, encryption will not provide protection. You'll want to store keys in a secure parameter store.
4. **Digests for passwords.** Do not use md5 or any sha digest for hashing passwords, even if you use salt. PolyBcrypt is the only poly-crypto module designed for hashing passwords.

### AES Encryption

[](#aes-encryption)

#### Encrypt and decrypt with key

[](#encrypt-and-decrypt-with-key)

**Note:** key should be a 64-character hex-encoded string stored in a secure param store. To generate a cryptographically secure random key, use `PolyAES.generateKey(64)`.

NodeJS:

```
import { PolyAES } from 'poly-crypto';

const hexKey = '64-char hex encoded string from secure param store';
const encrypted = PolyAES.withKey(hexKey).encrypt(data);
const decrypted = PolyAES.withKey(hexKey).decrypt(encrypted);
```

PHP:

```
