Untitled
unknown
javascript
a year ago
5.7 kB
15
Indexable
import sodium from "libsodium-wrappers-sumo"
const transformValueToHex = async (value: string | Uint8Array) => {
await sodium.ready
return sodium.to_hex(value)
}
const transformValueToBin = async (value: string) => {
await sodium.ready
return sodium.from_hex(value)
}
const generateMasterKey = async (password: string, userNonce = null) => {
try {
await sodium.ready
const nonce = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES)
const key = sodium.crypto_pwhash(
sodium.crypto_secretbox_KEYBYTES, // Taille de la clé
password, // Mot de passe pour la dérivation
userNonce ? userNonce : nonce, // Sel pour la dérivation
sodium.crypto_pwhash_OPSLIMIT_MODERATE, // Nombre d'opérations (complexité)
sodium.crypto_pwhash_MEMLIMIT_MODERATE, // Mémoire utilisée
sodium.crypto_pwhash_ALG_ARGON2ID13, // Algorithme Argon2id
)
return { key: key, nonce: userNonce ? userNonce : nonce }
} catch (error) {
console.error(
"Erreur lors de la génération de la clé maîtresse:",
error,
)
}
}
const generateKeyPair = async (masterKey: Uint8Array) => {
await sodium.ready
const keyPair = sodium.crypto_box_keypair()
const { encryptedPrivateKey, noncePrivate } = await encryptPrivateKey(
keyPair.privateKey,
masterKey,
)
const noncePublic = sodium.randombytes_buf(
sodium.crypto_secretbox_NONCEBYTES,
)
return {
publicKey: keyPair.publicKey,
privateKey: encryptedPrivateKey,
noncePrivateKey: noncePrivate,
noncePublic: noncePublic,
}
}
const generateCredentialKeyPair = async (publicKey: string) => {
await sodium.ready
const keyPair = sodium.crypto_box_keypair()
const encryptedCategoryPrivateKey = sodium.crypto_box_seal(
keyPair.privateKey,
sodium.from_hex(publicKey),
)
return {
credentialPublicKey: sodium.to_hex(keyPair.publicKey),
credentialPrivateKey: sodium.to_hex(encryptedCategoryPrivateKey),
}
}
const encryptPublicKey = async (
publicKey: string,
isForDemo: boolean,
firstHash: Uint8Array,
secondHash: Uint8Array,
) => {
await sodium.ready
const textEncoder = new TextEncoder()
const nonceEncryptedPublicKey = sodium.randombytes_buf(
sodium.crypto_secretbox_NONCEBYTES,
)
const firstHashForDemo = textEncoder.encode("0123456789abcdefghijvbnm")
const secondHashForDemo = textEncoder.encode(
"827ccb0eea8a706c4c34a16891f84e7b",
)
// Ici les hash sont en dur, mais seront dynamiques plus tard
const encryptedPublicKey = sodium.crypto_secretbox_easy(
publicKey,
isForDemo ? secondHashForDemo : secondHash,
isForDemo ? firstHashForDemo : firstHash,
)
return { encryptedPublicKey, nonceEncryptedPublicKey }
}
// Chiffre la clé privée, renvoie la clé chiffrée avec son nonce pour l'envoyer en base
const encryptPrivateKey = async (
privateKey: Uint8Array,
masterKey: Uint8Array,
) => {
await sodium.ready
const noncePrivate = sodium.randombytes_buf(
sodium.crypto_secretbox_NONCEBYTES,
)
const encryptedPrivateKey = sodium.crypto_secretbox_easy(
privateKey,
noncePrivate,
masterKey,
)
return { encryptedPrivateKey, noncePrivate }
}
// Décrypte les mdp, fichiers... Avec la clé privée
const decryptPrivateKey = async (
encryptedPrivateKey: string,
privateKeyNonce: Uint8Array,
masterKey: Uint8Array,
) => {
await sodium.ready
try {
const decrypted = sodium.crypto_secretbox_open_easy(
encryptedPrivateKey,
privateKeyNonce,
masterKey,
)
return { decrypted }
} catch (e) {
console.error(e)
return { decryptedError: e }
}
}
// Gérer le chiffrement avec la clé publique
const encryptWithPublicKey = async (data: string, publicKey: string) => {
await sodium.ready
const encryptedData = sodium.crypto_box_seal(
data,
sodium.from_hex(publicKey),
)
return encryptedData
}
const encryptPasswordWithPublicKey = async (
data: string,
publicKey: string,
) => {
await sodium.ready
const encodedData = sodium.from_string(data)
const encryptedData = sodium.crypto_box_seal(
encodedData,
sodium.from_hex(publicKey),
)
return encryptedData
}
const importKey = async (masterKey: Uint8Array) => {
return await window.crypto.subtle.importKey(
"raw",
masterKey,
{ name: "AES-GCM" },
false,
["encrypt", "decrypt"],
)
}
const encryptString = async (str: string, key: CryptoKey) => {
const iv = window.crypto.getRandomValues(new Uint8Array(12))
const encoder = new TextEncoder()
const encoded = encoder.encode(str)
const encrypted = await window.crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
key,
encoded,
)
return { encrypted, iv }
}
const handleEncrypt = async (dataToEncrypt: string, masterKey: Uint8Array) => {
try {
const key = await importKey(masterKey)
const encrypted = await encryptString(dataToEncrypt, key)
return encrypted
} catch (error) {
console.error("Erreur lors du chiffrement:", error)
}
}
// Gestion du déchiffrement
const handleDecrypt = async (encryptedData: string, privateKey: Uint8Array) => {
try {
await sodium.ready
const publicKey = sodium.crypto_scalarmult_base(privateKey)
const decryptedKey = sodium.crypto_box_seal_open(
sodium.from_hex(encryptedData),
publicKey,
privateKey,
)
return sodium.from_hex(sodium.to_string(decryptedKey))
} catch (error) {
console.error("Erreur lors du déchiffrement:", error)
}
}
const signTokenWithKey = async (tokenXLS: string, key: Uint8Array) => {
await sodium.ready
return sodium.crypto_sign_detached(tokenXLS, key)
}
export {
generateMasterKey,
generateKeyPair,
generateCredentialKeyPair,
encryptPublicKey,
encryptPrivateKey,
decryptPrivateKey,
encryptWithPublicKey,
encryptPasswordWithPublicKey,
importKey,
handleEncrypt,
handleDecrypt,
transformValueToBin,
transformValueToHex,
signTokenWithKey,
}
Editor is loading...
Leave a Comment