Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@1auth/crypto

Package Overview
Dependencies
Maintainers
0
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@1auth/crypto - npm Package Compare versions

Comparing version 0.0.0-alpha.44 to 0.0.0-alpha.45

244

index.js

@@ -21,26 +21,35 @@ import { promisify } from 'node:util'

const defaults = {
// symetricEncryptionKey: randomBytes(32).toString('base64') // 256 bits
symetricEncryptionKey: undefined,
symetricEncryptionMethod: 'chacha20-poly1305', // 2024-05: AES-256 GCM (aes-256-gcm) or ChaCha20-Poly1305 (chacha20-poly1305)
symetricEncryptionEncoding: 'base64', // https://nodejs.org/api/buffer.html#buffers-and-character-encodings
asymetricKey: 'P-384',
// symmetricEncryptionKey: randomBytes(32).toString('base64') // 256 bits
symmetricEncryptionKey: undefined,
symmetricEncryptionMethod: 'chacha20-poly1305', // 2024-05: AES-256 GCM (aes-256-gcm) or ChaCha20-Poly1305 (chacha20-poly1305)
symmetricEncryptionEncoding: 'base64', // https://nodejs.org/api/buffer.html#buffers-and-character-encodings
symmetricSignatureAlgorithm: 'sha3-384',
// symmetricSignatureSecret: randomBytes(32).toString('base64') // 256 bits
symmetricSignatureSecret: undefined,
asymmetricKeyNamedCurve: 'P-384', // P-512
asymmetricSignatureAlgorithm: 'sha3-384',
digestAlgorithm: 'sha3-384',
hmacAlgorithm: 'sha256',
digestEncoding: 'hex',
signatureEncoding: 'base64'
}
const symetricEncryptionEncodingLengths = {}
const symmetricEncryptionEncodingLengths = {}
const options = {}
export default (opt = {}) => {
Object.assign(options, defaults, opt)
symetricEncryptionEncodingLengths.iv = randomBytes(12).toString(
options.symetricEncryptionEncoding
symmetricEncryptionEncodingLengths.iv = randomBytes(12).toString(
options.symmetricEncryptionEncoding
).length
symetricEncryptionEncodingLengths.ivAndAuthTag =
symetricEncryptionEncodingLengths.iv +
randomBytes(16).toString(options.symetricEncryptionEncoding).length
if (!options.symetricEncryptionKey) {
symmetricEncryptionEncodingLengths.ivAndAuthTag =
symmetricEncryptionEncodingLengths.iv +
randomBytes(16).toString(options.symmetricEncryptionEncoding).length
if (!options.symmetricEncryptionKey) {
console.warn(
"@1auth/crypto symetricEncryptionKey is empty, use a stored secret made from randomBytes(32).toString('base64'). Encryption disabled."
"@1auth/crypto symmetricEncryptionKey is empty, use a stored secret made from randomBytes(32).toString('base64'). Encryption disabled."
)
}
if (!options.symmetricSignatureSecret) {
console.warn(
"@1auth/crypto symmetricSignatureSecret is empty, use a stored secret made from randomBytes(32).toString('base64'). Signature disabled."
)
}
}

@@ -130,6 +139,2 @@

export const randomSymetricEncryptionKey = () => {
return randomBytes(32).toString('base64') // 256 bits
}
// *** configs *** //

@@ -145,5 +150,6 @@ export const randomId = {

// *** Digests *** //
export const createChecksum = (value, { algorithm } = {}) => {
export const createChecksum = (value, { algorithm, encoding } = {}) => {
algorithm ??= options.digestAlgorithm
return checksum(algorithm).update(value).digest('hex')
encoding ??= options.digestEncoding
return checksum(algorithm).update(value).digest(encoding)
}

@@ -159,15 +165,16 @@ export const createDigest = (value, { algorithm } = {}) => {

export const createEncryptedDigest = (value, { algorithm } = {}) => {
algorithm ??= options.digestAlgorithm
const digest = createDigest(value, { algorithm })
// encrypting using the symetricEncryptionKey instread of
// encrypting using the symmetricEncryptionKey instead of
// the row encryptionKey to allow lookup, must have fixed iv
return symetricEncrypt(digest, {
encryptionKey: options.symetricEncryptionKey,
return symmetricEncrypt(digest, {
encryptionKey: options.symmetricEncryptionKey,
sub: '',
encoding: options.symetricEncryptionEncoding,
encoding: options.symmetricEncryptionEncoding,
iv: Buffer.from(
options.symetricEncryptionKey.substring(
options.symmetricEncryptionKey.substring(
0,
symetricEncryptionEncodingLengths.iv
symmetricEncryptionEncodingLengths.iv
),
options.symetricEncryptionEncoding
options.symmetricEncryptionEncoding
)

@@ -182,15 +189,15 @@ })

) => {
const digest = symetricDecrypt(encryptedValue, {
const digest = symmetricDecrypt(encryptedValue, {
encryptionKey,
sub: '',
encoding: options.symetricEncryptionEncoding
encoding: options.symmetricEncryptionEncoding
})
return symetricEncrypt(digest, {
return symmetricEncrypt(digest, {
encryptionKey: newEncryptionKey,
sub: '',
encoding: options.symetricEncryptionEncoding,
encoding: options.symmetricEncryptionEncoding,
iv: Buffer.from(
newEncryptionKey.substring(0, symetricEncryptionEncodingLengths.iv),
options.symetricEncryptionEncoding
newEncryptionKey.substring(0, symmetricEncryptionEncodingLengths.iv),
options.symmetricEncryptionEncoding
)

@@ -219,15 +226,19 @@ })

// *** Encryption *** //
// *** Symmetric Encryption *** //
const authTagLength = 16
export const makeSymetricKey = (sub) => {
if (!options.symetricEncryptionKey) {
export const symmetricRandomEncryptionKey = () => {
return randomBytes(32).toString('base64') // 256 bits
}
export const symmetricGenerateEncryptionKey = (sub) => {
if (!options.symmetricEncryptionKey) {
return { encryptionKey: '', encryptedKey: '' }
}
const encryptionKey = randomSymetricEncryptionKey()
const encryptedKey = symetricEncrypt(encryptionKey, {
encryptionKey: options.symetricEncryptionKey,
const encryptionKey = symmetricRandomEncryptionKey()
const encryptedKey = symmetricEncrypt(encryptionKey, {
encryptionKey: options.symmetricEncryptionKey,
sub,
decoding: 'base64',
encoding: options.symetricEncryptionEncoding
encoding: options.symmetricEncryptionEncoding
})

@@ -244,3 +255,3 @@ return { encryptionKey, encryptedKey }

if (encryptedKey) {
encryptionKey ??= symetricDecryptKey(encryptedKey, {
encryptionKey ??= symmetricDecryptKey(encryptedKey, {
sub

@@ -252,3 +263,3 @@ })

for (const key of fields) {
encryptedValues[key] &&= symetricEncrypt(encryptedValues[key], {
encryptedValues[key] &&= symmetricEncrypt(encryptedValues[key], {
encryptionKey,

@@ -261,8 +272,8 @@ sub

export const symetricEncrypt = (
export const symmetricEncrypt = (
data,
{ encryptedKey, encryptionKey, sub, decoding, encoding, iv }
{ encryptedKey, encryptionKey, signatureSecret, sub, decoding, encoding, iv }
) => {
if (encryptedKey) {
encryptionKey ??= symetricDecryptKey(encryptedKey, {
encryptionKey ??= symmetricDecryptKey(encryptedKey, {
sub

@@ -273,7 +284,7 @@ })

decoding ??= 'utf8'
encoding ??= options.symetricEncryptionEncoding
encoding ??= options.symmetricEncryptionEncoding
iv ??= randomBytes(12) // 96 bits
const cipher = createCipheriv(
options.symetricEncryptionMethod,
options.symmetricEncryptionMethod,
Buffer.from(encryptionKey, 'base64'),

@@ -293,3 +304,4 @@ iv,

return encryptedDataPacket
// add signature to end
return symmetricSignatureSign(encryptedDataPacket, signatureSecret)
}

@@ -299,7 +311,7 @@

encryptedValues,
{ encryptedKey, encryptionKey, sub },
{ encryptedKey, encryptionKey, signatureSecret, sub },
fields = []
) => {
if (encryptedKey) {
encryptionKey ??= symetricDecryptKey(encryptedKey, {
encryptionKey ??= symmetricDecryptKey(encryptedKey, {
sub

@@ -311,3 +323,3 @@ })

for (const key of fields) {
values[key] &&= symetricDecrypt(values[key], {
values[key] &&= symmetricDecrypt(values[key], {
encryptionKey,

@@ -320,7 +332,7 @@ sub

export const symetricDecryptKey = (encryptedKey, { sub } = {}) => {
return symetricDecrypt(encryptedKey, {
encryptionKey: options.symetricEncryptionKey,
export const symmetricDecryptKey = (encryptedKey, { sub } = {}) => {
return symmetricDecrypt(encryptedKey, {
encryptionKey: options.symmetricEncryptionKey,
sub,
decoding: options.symetricEncryptionEncoding,
decoding: options.symmetricEncryptionEncoding,
encoding: 'base64'

@@ -330,8 +342,8 @@ })

export const symetricDecrypt = (
export const symmetricDecrypt = (
encryptedDataPacket,
{ encryptedKey, encryptionKey, sub, decoding, encoding }
{ encryptedKey, encryptionKey, signatureSecret, sub, decoding, encoding }
) => {
if (encryptedKey) {
encryptionKey ??= symetricDecryptKey(encryptedKey, {
encryptionKey ??= symmetricDecryptKey(encryptedKey, {
sub

@@ -341,7 +353,17 @@ })

if (!encryptionKey || !encryptedDataPacket) return encryptedDataPacket
decoding ??= options.symetricEncryptionEncoding
decoding ??= options.symmetricEncryptionEncoding
encoding ??= 'utf8'
// remove signature when successful
encryptedDataPacket = symmetricSignatureVerify(
encryptedDataPacket,
signatureSecret
)
if (encryptedDataPacket === false) {
throw new Error('Signature incorrect')
}
const iv = Buffer.from(
encryptedDataPacket.substring(0, symetricEncryptionEncodingLengths.iv),
encryptedDataPacket.substring(0, symmetricEncryptionEncodingLengths.iv),
decoding

@@ -351,4 +373,4 @@ )

encryptedDataPacket.substring(
symetricEncryptionEncodingLengths.iv,
symetricEncryptionEncodingLengths.ivAndAuthTag
symmetricEncryptionEncodingLengths.iv,
symmetricEncryptionEncodingLengths.ivAndAuthTag
),

@@ -359,3 +381,3 @@ decoding

encryptedDataPacket.substring(
symetricEncryptionEncodingLengths.ivAndAuthTag
symmetricEncryptionEncodingLengths.ivAndAuthTag
),

@@ -366,3 +388,3 @@ decoding

const decipher = createDecipheriv(
options.symetricEncryptionMethod,
options.symmetricEncryptionMethod,
Buffer.from(encryptionKey, 'base64'),

@@ -383,7 +405,61 @@ iv,

// *** Signatures *** //
// *** Symmetric Signatures *** //
export const symmetricRandomSignatureSecret = () => {
return randomBytes(32).toString('base64') // 256 bits
}
export const symmetricGenerateSignatureSecret = (sub) => {
if (!options.symmetricSignatureSecret) {
return { signatureSecret: '' }
}
const signatureSecret = symmetricRandomSignatureSecret()
return { signatureSecret }
}
export const symmetricSignatureSign = (
data,
signatureSecret,
{ algorithm } = {}
) => {
// if (typeof data !== 'string') throw new TypeError('data must me a string')
signatureSecret ??= options.symmetricSignatureSecret
algorithm ??= options.symmetricSignatureAlgorithm
const signature = createHmac(algorithm, signatureSecret)
.update(data)
.digest(options.signatureEncoding)
.replace(/=+$/, '')
const signedData = data + '.' + signature
return signedData
}
export const symmetricSignatureVerify = (
signedData,
signatureSecret,
{ algorithm } = {}
) => {
if (typeof signedData !== 'string') return false
const data = signedData.slice(0, signedData.lastIndexOf('.'))
const signedDataExpected = symmetricSignatureSign(data, signatureSecret, {
algorithm
})
return safeEqual(signedData, signedDataExpected) && data
}
export const symmetricRotation = (
encryptedValues,
oldOptions, // { encryptedKey, encryptionKey, signatureSecret, sub }, // old
newOptions, // { encryptedKey, encryptionKey, signatureSecret, sub, decoding, encoding, iv }, // new
fields = []
) => {
const data = symmetricDecryptFields(encryptedValues, oldOptions, fields)
const newEncryptedData = symmetricEncryptFields(data, newOptions, fields)
return newEncryptedData
}
// *** Asymmetric Signatures *** //
// asymmetricKeyPairType
export const makeAsymmetricKeys = async () => {
const { publicKey, privateKey } = await generateKeyPair('ec', {
namedCurve: 'P-384', // P-512
namedCurve: options.asymmetricKeyNamedCurve,
paramEncoding: 'named',

@@ -398,3 +474,3 @@ publicKeyEncoding: {

// Encryption done at another level for consistency
// cipher: options.asymetricEncryptionMethod,
// cipher: options.asymmetricEncryptionMethod,
// passphrase: encryptionKey,

@@ -411,3 +487,3 @@ }

) => {
algorithm ??= options.digestAlgorithm
algorithm ??= options.asymmetricSignatureAlgorithm
return (await sign(algorithm, Buffer.from(data), privateKey)).toString(

@@ -423,3 +499,3 @@ options.signatureEncoding

) => {
algorithm ??= options.digestAlgorithm
algorithm ??= options.asymmetricSignatureAlgorithm
return await verify(

@@ -433,32 +509,2 @@ algorithm,

export const makeSymmetricSignature = (
data,
encryptionKey,
{ algorithm } = {}
) => {
// if (typeof data !== 'string') throw new TypeError('data must me a string')
encryptionKey ??= options.symetricEncryptionKey
algorithm ??= options.hmacAlgorithm
const signature = createHmac('sha256', encryptionKey)
.update(data)
.digest('base64')
.replace(/=+$/, '')
const signedData = data + '.' + signature
return signedData
}
export const verifySymmetricSignature = (
signedData,
encryptionKey,
{ algorithm } = {}
) => {
if (typeof signedData !== 'string') return false
const data = signedData.slice(0, signedData.lastIndexOf('.'))
const signedDataExpected = makeSymmetricSignature(data, encryptionKey, {
algorithm
})
return safeEqual(signedData, signedDataExpected) && data
}
export const safeEqual = (input, expected) => {

@@ -465,0 +511,0 @@ const bufferInput = Buffer.from(input)

{
"name": "@1auth/crypto",
"version": "0.0.0-alpha.44",
"version": "0.0.0-alpha.45",
"description": "",

@@ -5,0 +5,0 @@ "type": "module",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc