Skip to content

Commit

Permalink
Added support for changing AES or RSA standard
Browse files Browse the repository at this point in the history
  • Loading branch information
juhoen committed Jul 27, 2020
1 parent 75d0526 commit c1c916b
Show file tree
Hide file tree
Showing 13 changed files with 730 additions and 1,807 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ var rsa = new RSA({ entropy: entropy });

// Select default message digest
var crypt = new Crypt({ md: 'sha512' });

// Select AES or RSA standard
var crypt = new Crypt({
// Default AES standard is AES-CBC. Options are:
// AES-ECB, AES-CBC, AES-CFB, AES-OFB, AES-CTR, AES-GCM, 3DES-ECB, 3DES-CBC, DES-ECB, DES-CBC
aesStandard: 'AES-CBC',
// Default RSA standard is RSA-OAEP. Options are:
// RSA-OAEP, RSAES-PKCS1-V1_5
rsaStandard: 'RSA-OAEP',
});

// Alternate AES keysize (some AES algorithms requires specific key size)
var crypt = new Crypt({
aesKeySize: 192, // Defaults to 256
});
```

### Encryption
Expand Down Expand Up @@ -215,6 +230,5 @@ rsa.generateKeyPair(function(keyPair) {
// RSA can be also initialized with options
var rsa = new RSA({
keySize: 4096,
rsaStandard: 'RSA-OAEP', // RSA-OAEP or RSAES-PKCS1-V1_5,
});
```
4 changes: 3 additions & 1 deletion lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

module.exports = {
AES_STANDARD: 'AES-CBC',
DEFAULT_MESSAGE_DIGEST: 'sha256'
RSA_STANDARD: 'RSA-OAEP',
DEFAULT_MESSAGE_DIGEST: 'sha256',
DEFAULT_AES_KEY_SIZE: 256
};
34 changes: 24 additions & 10 deletions lib/crypt.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
"use strict";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
Expand All @@ -15,7 +21,9 @@ var pki = forge.pki,

var _require = require('./constants'),
DEFAULT_MESSAGE_DIGEST = _require.DEFAULT_MESSAGE_DIGEST,
AES_STANDARD = _require.AES_STANDARD;
DEFAULT_AES_KEY_SIZE = _require.DEFAULT_AES_KEY_SIZE,
AES_STANDARD = _require.AES_STANDARD,
RSA_STANDARD = _require.RSA_STANDARD;

var Crypt =
/*#__PURE__*/
Expand All @@ -25,8 +33,11 @@ function () {

_classCallCheck(this, Crypt);

this.options = Object.assign({}, {
this.options = _objectSpread({
md: DEFAULT_MESSAGE_DIGEST,
aesKeySize: DEFAULT_AES_KEY_SIZE,
aesStandard: AES_STANDARD,
rsaStandard: RSA_STANDARD,
entropy: undefined
}, options); // Add some entropy if available

Expand Down Expand Up @@ -196,19 +207,19 @@ function () {
}); // Generate random keys

var iv = forge.random.getBytesSync(32);
var key = forge.random.getBytesSync(32); // Encrypt random key with all of the public keys
var key = forge.random.getBytesSync(this.options.aesKeySize / 8); // Encrypt random key with all of the public keys

var encryptedKeys = {};
publicKeys.forEach(function (publicKey) {
var encryptedKey = publicKey.encrypt(key, 'RSA-OAEP');
var encryptedKey = publicKey.encrypt(key, _this.options.rsaStandard);

var fingerprint = _this.fingerprint(publicKey);

encryptedKeys[fingerprint] = forge.util.encode64(encryptedKey);
}); // Create buffer and cipher

var buffer = forge.util.createBuffer(message, 'utf8');
var cipher = forge.cipher.createCipher(AES_STANDARD, key); // Actual encryption
var cipher = forge.cipher.createCipher(this.options.aesStandard, key); // Actual encryption

cipher.start({
iv: iv
Expand All @@ -221,7 +232,8 @@ function () {
payload.iv = forge.util.encode64(iv);
payload.keys = encryptedKeys;
payload.cipher = forge.util.encode64(cipher.output.data);
payload.signature = signature; // Return encrypted message
payload.signature = signature;
payload.tag = cipher.mode.tag && forge.util.encode64(cipher.mode.tag.getBytes()); // Return encrypted message

return JSON.stringify(payload);
}
Expand Down Expand Up @@ -255,15 +267,17 @@ function () {

var keyBytes = forge.util.decode64(encryptedKey);
var iv = forge.util.decode64(payload.iv);
var cipher = forge.util.decode64(payload.cipher); // Use RSA to decrypt AES key
var cipher = forge.util.decode64(payload.cipher);
var tag = payload.tag && forge.util.decode64(payload.tag); // Use RSA to decrypt AES key

var key = privateKey.decrypt(keyBytes, 'RSA-OAEP'); // Create buffer and decipher
var key = privateKey.decrypt(keyBytes, this.options.rsaStandard); // Create buffer and decipher

var buffer = forge.util.createBuffer(cipher);
var decipher = forge.cipher.createDecipher(AES_STANDARD, key); // Actual decryption
var decipher = forge.cipher.createDecipher(this.options.aesStandard, key); // Actual decryption

decipher.start({
iv: iv
iv: iv,
tag: tag
});
decipher.update(buffer);
decipher.finish(); // Return utf-8 encoded bytes
Expand Down
14 changes: 11 additions & 3 deletions lib/rsa.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
"use strict";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
Expand All @@ -18,12 +24,14 @@ function () {

_classCallCheck(this, RSA);

this.options = Object.assign({}, {
this.options = _objectSpread({
keySize: 4096,
rsaStandard: 'RSA-OAEP',
entropy: undefined
}, options);
if (this.options.entropy) this._entropy(this.options.entropy);

if (this.options.entropy) {
this._entropy(this.options.entropy);
}
}
/**
* Generates RSA keypair
Expand Down
Loading

0 comments on commit c1c916b

Please sign in to comment.