https://github.com/namesmt/sencrypt
Simple encrypted secret helper
https://github.com/namesmt/sencrypt
Last synced: over 1 year ago
JSON representation
Simple encrypted secret helper
- Host: GitHub
- URL: https://github.com/namesmt/sencrypt
- Owner: NamesMT
- License: mit
- Created: 2024-07-25T08:02:27.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-03-08T11:03:03.000Z (over 1 year ago)
- Last Synced: 2025-03-10T04:42:57.409Z (over 1 year ago)
- Language: TypeScript
- Homepage:
- Size: 179 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# sencrypt 
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![Codecov][codecov-src]][codecov-href]
[![Bundlejs][bundlejs-src]][bundlejs-href]
[![jsDocs.io][jsDocs-src]][jsDocs-href]
**sencrypt** (SEncrypt - Stateful-salt Encryption)
SEncrypt is a collection of helpers to implement an encrypted secret system.
SEncrypt requires a storage interface to be passed in, which is used by `SHash` to store the stateful salt.
SEncrypt takes a `plaintext`, encrypts it with a secret hash generated by SHash (which requires a `salt`, `partition`, and `id`), and stores the ciphertext
SEncrypt extends upon and uses [**SHash**](https://github.com/NamesMT/shash) under-the-hood to manage the secret hash key.
Please take a look at SHash.
SEncrypt supports any encryption algorithm, it is recommended to use AES-GCM for the balance of security and performance,
Note: Encryption algorithm is not included in this package, you can use any encryption algorithm you want.
## Features
- [x] TypeScript ready!
## Usage
### Install package:
```sh
# npm
npm install @namesmt/sencrypt
# yarn
yarn add @namesmt/sencrypt
# pnpm (recommended)
pnpm install @namesmt/sencrypt
```
### Import and use:
```ts
// ESM
import { SEncrypt, SEncryptEncrypterInterface, SEncryptStorageInterface } from '@namesmt/sencrypt'
import { decrypt as aesGcmDecrypt, encrypt as aesGcmEncrypt } from '@namesmt/aes-gcm'
/**
* This is a simple in-memory storage implementation.
*
* This is not recommended for production use, but it is useful for testing.
*/
export class MemoryStorage implements SEncryptStorageInterface {
saltStore: Record = {}
cipherStore: Record = {}
async getSalt(partition: string, id: string) { return this.saltStore[`${partition}#${id}`] }
async setSalt(partition: string, id: string, value: string) { this.saltStore[`${partition}#${id}`] = value }
async getCiphertext(partition: string, id: string) { return this.cipherStore[`${partition}#${id}`] }
async setCiphertext(partition: string, id: string, value: string) { this.cipherStore[`${partition}#${id}`] = value }
}
export class AesGcmEncrypter implements SEncryptEncrypterInterface {
encrypt = aesGcmEncrypt
decrypt = aesGcmDecrypt
}
// A simple hash function for demo purposes
function demoHash(str: string) {
return `${str}-demohashed`
}
const {
encrypt, // Encrypts plaintext into ciphertext, secured with a hash key created from the given salt, partition and id.
encryptStore, // ^^^ but also stores the ciphertext into the storage.
decrypt, // Decrypts a ciphertext that was secured with a hash key created from the given salt, partition and id, back into plaintext.
decryptStored, // ^^^ but the ciphertext is retrieved from the storage.
decryptStoredFlash, // ^^^ and the ciphertext is deleted from the storage after decryption.
} = new SEncrypt(new MemoryStorage(), demoHash, new AesGcmEncrypter()) // You could pass in any hashing and encryption algorithm.
const encrypted = await encrypt('salt', 'partition', 'id', 'plaintext') // encrypted string of 'plaintext'
const decrypted = await decrypt('salt', 'partition', 'id', encrypted) // returns 'plaintext'
const storedEncrypted = await encryptStore('salt', 'partition', 'id', 'plaintext') // encrypted string of 'plaintext'
const storedDecrypted = await decryptStored('salt', 'partition', 'id') // returns 'plaintext'
const storedDecryptedFlash = await decryptStoredFlash('salt', 'partition', 'id') // returns 'plaintext'
const storedDecrypted_error = await decryptStored('salt', 'partition', 'id') // Should throw an error because the ciphertext is not found.
```
## Roadmap
- [ ] Become the legendary 10000x developer
## License [![License][license-src]][license-href]
[MIT](./LICENSE) License © 2024 [NamesMT](https://github.com/NamesMT)
[npm-version-src]: https://img.shields.io/npm/v/@namesmt/sencrypt?labelColor=18181B&color=F0DB4F
[npm-version-href]: https://npmjs.com/package/@namesmt/sencrypt
[npm-downloads-src]: https://img.shields.io/npm/dm/@namesmt/sencrypt?labelColor=18181B&color=F0DB4F
[npm-downloads-href]: https://npmjs.com/package/@namesmt/sencrypt
[codecov-src]: https://img.shields.io/codecov/c/gh/namesmt/sencrypt/main?labelColor=18181B&color=F0DB4F
[codecov-href]: https://codecov.io/gh/namesmt/sencrypt
[license-src]: https://img.shields.io/github/license/namesmt/sencrypt.svg?labelColor=18181B&color=F0DB4F
[license-href]: https://github.com/namesmt/sencrypt/blob/main/LICENSE
[bundlejs-src]: https://img.shields.io/bundlejs/size/@namesmt/sencrypt?labelColor=18181B&color=F0DB4F
[bundlejs-href]: https://bundlejs.com/?q=@namesmt/sencrypt
[jsDocs-src]: https://img.shields.io/badge/Check_out-jsDocs.io---?labelColor=18181B&color=F0DB4F
[jsDocs-href]: https://www.jsdocs.io/package/@namesmt/sencrypt