@mojsoski/server-crypto
Version:
Asymmetric key-exchange cryptography library
118 lines • 4.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BrowserCrypto = void 0;
const base64_utils_1 = require("../base64-utils");
function bufferToBase64url(buf) {
return (0, base64_utils_1.toBase64URL)(Buffer.from(buf).toString("base64"));
}
function base64urlToBuffer(base64url) {
return Buffer.from((0, base64_utils_1.normalizeBase64)(base64url), "base64");
}
function cryptoFrom() {
return {
async stringifyPrivateKey(key) {
const exported = await crypto.subtle.exportKey("pkcs8", key);
return bufferToBase64url(exported);
},
async stringifyPublicKey(key) {
const exported = await crypto.subtle.exportKey("spki", key);
return bufferToBase64url(exported);
},
async jwkPublicKey(key) {
const verifyKey = await crypto.subtle.importKey("spki", await crypto.subtle.exportKey("spki", key), {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
}, true, ["verify"]);
return await crypto.subtle.exportKey("jwk", verifyKey);
},
async parsePrivateKey(base64url) {
const keyData = base64urlToBuffer(base64url);
return await crypto.subtle.importKey("pkcs8", keyData, {
name: "RSA-OAEP",
hash: "SHA-256",
}, true, ["decrypt"]);
},
async parsePublicKey(base64url) {
const keyData = base64urlToBuffer(base64url);
return await crypto.subtle.importKey("spki", keyData, {
name: "RSA-OAEP",
hash: "SHA-256",
}, true, ["encrypt"]);
},
async randomBytes(amount) {
const array = new Uint8Array(amount);
crypto.getRandomValues(array);
return Buffer.from(array);
},
async publicEncrypt(data, publicKey) {
const encrypted = await crypto.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data);
return Buffer.from(encrypted);
},
async privateDecrypt(data, privateKey) {
const decrypted = await crypto.subtle.decrypt({ name: "RSA-OAEP" }, privateKey, data);
return Buffer.from(decrypted);
},
async encrypt(buffer, keyBuf, iv) {
const key = await crypto.subtle.importKey("raw", keyBuf, { name: "AES-GCM" }, false, ["encrypt"]);
const encrypted = await crypto.subtle.encrypt({
name: "AES-GCM",
iv,
tagLength: 128,
}, key, buffer);
const data = new Uint8Array(encrypted);
const tag = data.slice(data.length - 16);
const content = data.slice(0, data.length - 16);
return {
authTag: Buffer.from(tag),
content: Buffer.from(content),
};
},
async decrypt(buffer, authTag, keyBuf, iv) {
const key = await crypto.subtle.importKey("raw", keyBuf, { name: "AES-GCM" }, false, ["decrypt"]);
const fullData = new Uint8Array([...buffer, ...authTag]);
const decrypted = await crypto.subtle.decrypt({
name: "AES-GCM",
iv,
tagLength: 128,
}, key, fullData);
return Buffer.from(decrypted);
},
};
}
function jwtFrom(module) {
return {
async signRS256(obj, privateKey, expiresIn) {
const signKey = await crypto.subtle.importKey("pkcs8", await crypto.subtle.exportKey("pkcs8", privateKey), {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
}, true, ["sign"]);
const alg = "RS256";
const jwt = await new module.SignJWT(obj)
.setProtectedHeader({ alg })
.setExpirationTime(expiresIn)
.setIssuedAt()
.sign(signKey);
return jwt;
},
async verifyRS256(jwt, publicKey) {
const verifyKey = await crypto.subtle.importKey("spki", await crypto.subtle.exportKey("spki", publicKey), {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
}, true, ["verify"]);
const { payload } = await module.jwtVerify(jwt, verifyKey, {
algorithms: ["RS256"],
});
return payload;
},
};
}
class BrowserCrypto {
constructor(jsonwebtoken) {
this.crypto = cryptoFrom();
this.jwt = jwtFrom(jsonwebtoken);
}
jwt;
crypto;
}
exports.BrowserCrypto = BrowserCrypto;
//# sourceMappingURL=browser-crypto.js.map