crypto-conditions
Version:
Implementation of crypto-conditions in JavaScript
121 lines (95 loc) • 4.04 kB
JavaScript
"use strict";
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
var _crypto = require("crypto");
var _pss = _interopRequireDefault(require("../crypto/pss"));
var _pem = _interopRequireDefault(require("../util/pem"));
/**
* @module types
*/
/**
* RSA-PSS using Node crypto module.
*
* This class combines Node's native crypto functionality with PSS padding
* implemented in this library.
*/
var Rsa = /*#__PURE__*/function () {
function Rsa(opts) {
(0, _classCallCheck2.default)(this, Rsa);
opts = opts || {};
this.hashAlgorithm = opts.hashAlgorithm || 'sha256';
this.pss = new _pss.default({
hashAlgorithm: this.hashAlgorithm
});
}
/**
* Get the length in bits of an RSA modulus.
*
* @param {Buffer} modulus RSA modulus.
* @return {Number} Number of bits in RSA modulus.
*/
(0, _createClass2.default)(Rsa, [{
key: "getModulusBitLength",
value: function getModulusBitLength(modulus) {
var modulusHighByteBitLength = modulus[0].toString(2).length;
var modulusBitLength = (modulus.length - 1) * 8 + modulusHighByteBitLength;
return modulusBitLength;
}
/**
* Sign a message using RSA-PSS.
*
* @param {String} privateKey PEM-encoded RSA private key.
* @param {Buffer} message Message to sign.
* @return {Buffer} RSA signature.
*/
}, {
key: "sign",
value: function sign(privateKey, message) {
// Calculate modulus bit length
var modulus = _pem.default.modulusFromPrivateKey(privateKey);
var modulusBitLength = this.getModulusBitLength(modulus); // Pad message using PSS
var encodedMessage = this.pss.encode(message, modulusBitLength - 1); // OpenSSL expects the message buffer to be the same length (in bytes) as
// the modulus.
var paddedMessage = encodedMessage.length < modulus.length ? (0, _concat.default)(Buffer).call(Buffer, [Rsa.ZERO_BYTE, encodedMessage]) : encodedMessage; // Sign
return (0, _crypto.privateEncrypt)({
key: privateKey,
padding: _crypto.constants.RSA_NO_PADDING
}, paddedMessage);
}
/**
* Verify a RSA-PSS signature.
*
* @param {Buffer} modulus RSA public modulus.
* @param {Buffer} message Message the signature should correspond to.
* @param {Buffer} signature RSA signature.
* @return {Boolean} Whether the signature is valid or not.
*/
}, {
key: "verify",
value: function verify(modulus, message, signature) {
// Verify signature
var publicKey = _pem.default.modulusToPem(modulus);
var paddedMessage = (0, _crypto.publicDecrypt)({
key: publicKey,
padding: _crypto.constants.RSA_NO_PADDING
}, signature); // OpenSSL returns a buffer that fits the bitlength of the modulus, but we
// need this buffer to be just long enough to fit the bitlength of the
// encodedMessage, which is one bit shorter.
var modulusBitLength = this.getModulusBitLength(modulus);
var encodedMessage = modulusBitLength % 8 === 1 ? (0, _slice.default)(paddedMessage).call(paddedMessage, 1) : paddedMessage; // Verify message padding
return this.pss.verify(message, encodedMessage, modulusBitLength - 1);
}
}]);
return Rsa;
}(); // Used to add a zero for padding
Rsa.ZERO_BYTE = Buffer.from([0]);
var _default = Rsa;
exports.default = _default;