react-native-quick-crypto
Version:
A fast implementation of Node's `crypto` module written in C/C++ JSI
164 lines (163 loc) • 5.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.privateDecrypt = privateDecrypt;
exports.privateEncrypt = privateEncrypt;
exports.publicDecrypt = publicDecrypt;
exports.publicEncrypt = publicEncrypt;
var _reactNativeNitroModules = require("react-native-nitro-modules");
var _utils = require("../utils");
var _utils2 = require("./utils");
var _classes = require("./classes");
var _constants = require("../constants");
function preparePublicCipherKey(key, isEncrypt) {
let keyObj;
let padding;
let oaepHash;
let oaepLabel;
if (key instanceof _classes.KeyObject) {
if (isEncrypt && key.type !== 'public') {
throw new Error('publicEncrypt requires a public key');
}
// publicDecrypt accepts both public and private keys (Node.js behavior)
// A private key contains the public components needed for verify_recover
keyObj = key;
} else if ((0, _utils2.isCryptoKey)(key)) {
const cryptoKey = key;
keyObj = cryptoKey.keyObject;
} else if ((0, _utils.isStringOrBuffer)(key)) {
const data = (0, _utils.binaryLikeToArrayBuffer)(key);
const isPem = typeof key === 'string' && key.includes('-----BEGIN');
const isPrivatePem = typeof key === 'string' && key.includes('-----BEGIN PRIVATE');
// publicDecrypt accepts both public and private keys (Node.js behavior)
if (!isEncrypt && isPrivatePem) {
keyObj = _classes.KeyObject.createKeyObject('private', data, _utils.KFormatType.PEM, _utils.KeyEncoding.PKCS8);
} else {
keyObj = _classes.KeyObject.createKeyObject('public', data, isPem ? _utils.KFormatType.PEM : _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
}
} else if (typeof key === 'object' && 'key' in key) {
const options = key;
const result = preparePublicCipherKey(options.key, isEncrypt);
keyObj = result.keyHandle;
padding = options.padding;
oaepHash = options.oaepHash;
if (options.oaepLabel) {
oaepLabel = (0, _utils.binaryLikeToArrayBuffer)(options.oaepLabel);
}
} else {
throw new Error('Invalid key input');
}
return {
keyHandle: keyObj,
padding,
oaepHash,
oaepLabel
};
}
function publicEncrypt(key, buffer) {
const {
keyHandle,
padding,
oaepHash,
oaepLabel
} = preparePublicCipherKey(key, true);
const rsaCipher = _reactNativeNitroModules.NitroModules.createHybridObject('RsaCipher');
const data = (0, _utils.binaryLikeToArrayBuffer)(buffer);
const paddingMode = padding ?? _constants.constants.RSA_PKCS1_OAEP_PADDING;
const hashAlgorithm = oaepHash || 'SHA-256';
try {
const encrypted = rsaCipher.encrypt(keyHandle.handle, data, paddingMode, hashAlgorithm, oaepLabel);
return Buffer.from(encrypted);
} catch (error) {
throw new Error(`publicEncrypt failed: ${error.message}`);
}
}
function publicDecrypt(key, buffer) {
const {
keyHandle,
padding
} = preparePublicCipherKey(key, false);
const rsaCipher = _reactNativeNitroModules.NitroModules.createHybridObject('RsaCipher');
const data = (0, _utils.binaryLikeToArrayBuffer)(buffer);
const paddingMode = padding ?? _constants.constants.RSA_PKCS1_PADDING;
try {
const decrypted = rsaCipher.publicDecrypt(keyHandle.handle, data, paddingMode);
return Buffer.from(decrypted);
} catch (error) {
throw new Error(`publicDecrypt failed: ${error.message}`);
}
}
function preparePrivateCipherKey(key, isEncrypt) {
let keyObj;
let padding;
let oaepHash;
let oaepLabel;
if (key instanceof _classes.KeyObject) {
if (isEncrypt && key.type !== 'private') {
throw new Error('privateEncrypt requires a private key');
}
if (!isEncrypt && key.type !== 'private') {
throw new Error('privateDecrypt requires a private key');
}
keyObj = key;
} else if ((0, _utils2.isCryptoKey)(key)) {
const cryptoKey = key;
keyObj = cryptoKey.keyObject;
} else if ((0, _utils.isStringOrBuffer)(key)) {
const data = (0, _utils.binaryLikeToArrayBuffer)(key);
const isPem = typeof key === 'string' && key.includes('-----BEGIN');
keyObj = _classes.KeyObject.createKeyObject('private', data, isPem ? _utils.KFormatType.PEM : _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
} else if (typeof key === 'object' && 'key' in key) {
const options = key;
const result = preparePrivateCipherKey(options.key, isEncrypt);
keyObj = result.keyHandle;
padding = options.padding;
oaepHash = options.oaepHash;
if (options.oaepLabel) {
oaepLabel = (0, _utils.binaryLikeToArrayBuffer)(options.oaepLabel);
}
} else {
throw new Error('Invalid key input');
}
return {
keyHandle: keyObj,
padding,
oaepHash,
oaepLabel
};
}
function privateEncrypt(key, buffer) {
const {
keyHandle,
padding
} = preparePrivateCipherKey(key, true);
const rsaCipher = _reactNativeNitroModules.NitroModules.createHybridObject('RsaCipher');
const data = (0, _utils.binaryLikeToArrayBuffer)(buffer);
const paddingMode = padding ?? _constants.constants.RSA_PKCS1_PADDING;
try {
const encrypted = rsaCipher.privateEncrypt(keyHandle.handle, data, paddingMode);
return Buffer.from(encrypted);
} catch (error) {
throw new Error(`privateEncrypt failed: ${error.message}`);
}
}
function privateDecrypt(key, buffer) {
const {
keyHandle,
padding,
oaepHash,
oaepLabel
} = preparePrivateCipherKey(key, false);
const rsaCipher = _reactNativeNitroModules.NitroModules.createHybridObject('RsaCipher');
const data = (0, _utils.binaryLikeToArrayBuffer)(buffer);
const paddingMode = padding ?? _constants.constants.RSA_PKCS1_OAEP_PADDING;
const hashAlgorithm = oaepHash || 'SHA-256';
try {
const decrypted = rsaCipher.privateDecrypt(keyHandle.handle, data, paddingMode, hashAlgorithm, oaepLabel);
return Buffer.from(decrypted);
} catch (error) {
throw new Error(`privateDecrypt failed: ${error.message}`);
}
}
//# sourceMappingURL=publicCipher.js.map