Skip to content

Releases: paragonie/ciphersweet

Version 4.1.0

14 Nov 10:15
v4.1.0
Compare
Choose a tag to compare
  • Add setActiveTenant() to EncryptedFile

Version 3.3.0

14 Nov 10:18
v3.3.0
Compare
Choose a tag to compare
  • Add setActiveTenant() to EncryptedFile

Version 4.0.2

28 Sep 02:33
v4.0.2
Compare
Choose a tag to compare
  • #74, #76 - Use the new #[\SensitiveParameter] attribute for PHP 8.2
  • Added tests generated from CipherSweet-JS to ensure interop

Version 4.0.1

02 Jun 15:27
v4.0.1
Compare
Choose a tag to compare
  • Fix #73
  • Fix #72
  • Expanded unit tests to prevent regressions

Version 4.0.0

21 May 19:14
v4.0.0
Compare
Choose a tag to compare
  • Requires PHP 8.1 or newer
  • CipherSweet v4 uses a strictly-typed API and cuts a modest amount of polyfill code for supporting older PHP versions

Version 3.2.1

21 May 17:50
v3.2.1
Compare
Choose a tag to compare
  • Fix: Strictness mode wasn't being passed from EncryptedRow to EncryptedJsonField.

Version 3.2.0

21 May 17:02
v3.2.0
Compare
Choose a tag to compare

New feature: EncryptedJsonField

If you're using a modern SQL database that supports JSON documents in each row (i.e. PostgreSQL with JSONB), this new feature allows you to encrypt a subset of a JSON document at rest.

<?php
use ParagonIE\CipherSweet\CipherSweet;
use ParagonIE\CipherSweet\EncryptedJsonField;
use ParagonIE\CipherSweet\EncryptedRow;
use ParagonIE\CipherSweet\JsonFieldMap;

/** @var CipherSweet $engine */

// Create a JSON Field Map
$map = (new JsonFieldMap())
    ->addTextField('name')
    ->addBooleanField('active')
    // You can describe a full path to an attribute of a JSON document by passing an array describing it:
    ->addIntegerField(['address', 0, 'zip_code'])
    ->addIntegerField('age');

// Instantiate the JSON field on an EncryptedRow:
$encRow = (new EncryptedRow($engine, 'table_name'))
    ->addJsonField('column', $map);

// You can also do this (if you want it in isolation):
$jsonField = EncryptedJsonField::create($engine, $map, 'table_name', 'column');

// Encrypt some data
$plaintext = [
    'user_id' => 3495,
    'extra' => 'foo bar baz ...',
    // This is the JSON column:
    'column' => [
        'active' => false,
        'name' => 'John Doe',
        'address' => [
            [
                'line1' => '1600 Pennsylvania Ave NW',
                'line2' => '',
                'city' => 'Washington',
                'state' => 'DC',
                'zip_code' => 20500
            ]
        ],
        'age' => 33
    ],
    'extraneous' => 1
];

$encrypted = $encRow->encryptRow($plaintext);
var_dump($encrypted);

This should produce output similar to this (albeit with different ciphertext):

array(4) {
  ["user_id"]=>
  int(3495)
  ["extra"]=>
  string(15) "foo bar baz ..."
  ["column"]=>
  string(499) "{"active":"brng:K9DpP-000NEi1NwRP78fFQ7-Z7PDTR1vWPzb2LfZWMvHELDIZRFjh5KjDnNxC7JXUBhuyg8cNllu","name":"brng:bs039aez6fF-jttL65ZDMKI-OQe-CfvYHhjEir3AHL
Smt9OhivZwy6SI7aMNRzmWQEWThXfICtxq3DVoPJNuAw==","address":[{"line1":"1600 Pennsylvania Ave NW","line2":"","city":"Washington","state":"DC","zip_code":"brng:0CwKzWzj
HhCNS_1A0WLlZCnkv5iiTgP1cBUsHJuIMVLREJIef88eYFJR3RjB2j6_LEz7SiuONOKJXIxW9bYzdA=="}],"age":"brng:sIMNt1UG7FuyLGHQfS9FEsDv6HJuXRJaVeUyWUQ4GY15vZ_G21qJ2KadAMCc9VXcwMPG
OSQ89acrbCc6cRQJ1w=="}"
  ["extraneous"]=>
  int(1)
}

This serializes the encrypted JSON blobs as a string. During decryption, a string is expected as input, and it will return an array once decoded.

$decrypted = $encRow->decryptRow($encrypted);
var_dump($decrypted);

This will yield the following:

array(4) {
  ["user_id"]=>
  int(3495)
  ["extra"]=>
  string(15) "foo bar baz ..."
  ["column"]=>
  array(4) {
    ["active"]=>
    bool(false)
    ["name"]=>
    string(8) "John Doe"
    ["address"]=>
    array(1) {
      [0]=>
      array(5) {
        ["line1"]=>
        string(24) "1600 Pennsylvania Ave NW"
        ["line2"]=>
        string(0) ""
        ["city"]=>
        string(10) "Washington"
        ["state"]=>
        string(2) "DC"
        ["zip_code"]=>
        int(20500)
      }
    }
    ["age"]=>
    int(33)
  }
  ["extraneous"]=>
  int(1)
}

Version 3.1.0

04 May 17:55
v3.1.0
Compare
Choose a tag to compare
  • Bugfix: The getTenant($name) method on the MultiTenantKeyProvider class incorrectly only returned the active tenant. This is fixed.
  • Added the getKeyProvider() method to CipherSweet. This is useful for calling methods on a multi-tenant-aware KeyProvider class (i.e. the parent one that wraps other KeyProvider classes).

Version 3.0.1

07 Jul 15:12
v3.0.1
55cb571
Compare
Choose a tag to compare
  • Handle NULLs more gracefully in EncryptedRow's decryption path. Fixes #62. (Thanks @lekoala!)

Version 3.0.0

21 Jun 02:14
v3.0.0
Compare
Choose a tag to compare
  • Backwards Compatibility breaks
  • Introduce a variant of ModernCrypto called BoringCrypto which uses BLAKE2b-MAC instead of Poly1305.
    • BoringCrypto and FIPSCrypto are both suitable for use in multi-tenant data storage situations.
  • Added support for key providers that make multi-tenant setups possible.
  • See https://ciphersweet.paragonie.com for updated documentation.