Skip to content

Commit 969bebe

Browse files
authored
feat: replace symmetric encryption algorithm by aes-256-gcm (#233)
1 parent 20c5e95 commit 969bebe

File tree

18 files changed

+219
-53
lines changed

18 files changed

+219
-53
lines changed

.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
"abi",
1919
"aes",
2020
"aes256cbc",
21+
"aes256gcm",
2122
"api",
2223
"arrayish",
2324
"arg",
2425
"args",
2526
"argv",
2627
"async",
28+
"auth",
2729
"axios",
2830
"blockchain",
2931
"blockcypher",
@@ -64,6 +66,7 @@
6466
"fau",
6567
"fetchable",
6668
"filename",
69+
"gcm",
6770
"gnosis",
6871
"gwei",
6972
"hexlify",

packages/integration-test/test/layers.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ describe('Request system', () => {
462462
const request = await requestLogic.getRequestFromId(resultCreation.result.requestId);
463463

464464
assert.exists(request.result);
465-
assert.equal(request.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
465+
assert.equal(request.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
466466
assert.isNull(request.result.request);
467467
assert.exists(request.result.pending);
468468
assert.equal(request.result.pending!.expectedAmount, '12345678987654321');
@@ -474,15 +474,15 @@ describe('Request system', () => {
474474
payeeIdentity,
475475
);
476476

477-
assert.equal(resultReduce.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
477+
assert.equal(resultReduce.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
478478
assert.isUndefined(resultReduce.result);
479479

480480
const requestAfterReduce = await requestLogic.getRequestFromId(resultCreation.result.requestId);
481481

482482
assert.exists(requestAfterReduce.result);
483483
assert.equal(
484484
requestAfterReduce.meta.transactionManagerMeta.encryptionMethod,
485-
'ecies-aes256-cbc',
485+
'ecies-aes256-gcm',
486486
);
487487
assert.exists(requestAfterReduce.result.request);
488488
assert.equal(requestAfterReduce.result.request!.expectedAmount, '12345678987654321');
@@ -497,15 +497,15 @@ describe('Request system', () => {
497497
payerIdentity,
498498
);
499499

500-
assert.equal(resultAccept.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
500+
assert.equal(resultAccept.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
501501
assert.isUndefined(resultAccept.result);
502502

503503
const requestAfterAccept = await requestLogic.getRequestFromId(resultCreation.result.requestId);
504504

505505
assert.exists(requestAfterAccept.result);
506506
assert.equal(
507507
requestAfterAccept.meta.transactionManagerMeta.encryptionMethod,
508-
'ecies-aes256-cbc',
508+
'ecies-aes256-gcm',
509509
);
510510
assert.exists(requestAfterAccept.result.request);
511511
assert.equal(requestAfterAccept.result.request!.state, RequestLogicTypes.STATE.CREATED);
@@ -519,7 +519,7 @@ describe('Request system', () => {
519519
payerIdentity,
520520
);
521521

522-
assert.equal(resultIncrease.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
522+
assert.equal(resultIncrease.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
523523
assert.isUndefined(resultIncrease.result);
524524

525525
const requestAfterIncrease = await requestLogic.getRequestFromId(
@@ -529,7 +529,7 @@ describe('Request system', () => {
529529
assert.exists(requestAfterIncrease.result);
530530
assert.equal(
531531
requestAfterIncrease.meta.transactionManagerMeta.encryptionMethod,
532-
'ecies-aes256-cbc',
532+
'ecies-aes256-gcm',
533533
);
534534
assert.exists(requestAfterIncrease.result.request);
535535
assert.equal(requestAfterIncrease.result.request!.expectedAmount, '12345678000000000');
@@ -543,15 +543,15 @@ describe('Request system', () => {
543543
payeeIdentity,
544544
);
545545

546-
assert.equal(resultCancel.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
546+
assert.equal(resultCancel.meta.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
547547
assert.isUndefined(resultCancel.result);
548548

549549
const requestAfterCancel = await requestLogic.getRequestFromId(resultCreation.result.requestId);
550550

551551
assert.exists(requestAfterCancel.result);
552552
assert.equal(
553553
requestAfterCancel.meta.transactionManagerMeta.encryptionMethod,
554-
'ecies-aes256-cbc',
554+
'ecies-aes256-gcm',
555555
);
556556
assert.exists(requestAfterCancel.result.request);
557557
assert.equal(requestAfterCancel.result.request!.state, RequestLogicTypes.STATE.ACCEPTED);

packages/integration-test/test/node-client.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ describe('Request client using a request node', () => {
325325
assert.isNull(requestData.balance);
326326
assert.exists(requestData.meta);
327327
assert.equal(requestData.pending!.state, Types.RequestLogic.STATE.CREATED);
328-
assert.equal(requestData.meta!.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
328+
assert.equal(requestData.meta!.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
329329

330330
// Fetch the created request by its id
331331
const fetchedRequest = await requestNetwork.fromRequestId(request.requestId);
@@ -337,7 +337,7 @@ describe('Request client using a request node', () => {
337337
assert.equal(requestData.expectedAmount, fetchedRequestData.expectedAmount);
338338
assert.isNull(requestData.balance);
339339
assert.exists(requestData.meta);
340-
assert.equal(requestData.meta!.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
340+
assert.equal(requestData.meta!.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
341341
});
342342

343343
it('can create an encrypted request, modify it and get it back unencrypted', async () => {
@@ -367,7 +367,7 @@ describe('Request client using a request node', () => {
367367
assert.isNull(requestData.balance);
368368
assert.exists(requestData.meta);
369369
assert.equal(requestData.pending!.state, Types.RequestLogic.STATE.CREATED);
370-
assert.equal(requestData.meta!.transactionManagerMeta.encryptionMethod, 'ecies-aes256-cbc');
370+
assert.equal(requestData.meta!.transactionManagerMeta.encryptionMethod, 'ecies-aes256-gcm');
371371

372372
await new Promise((resolve): any => request.on('confirmed', resolve));
373373

@@ -385,7 +385,7 @@ describe('Request client using a request node', () => {
385385
assert.exists(fetchedRequestData.meta);
386386
assert.equal(
387387
fetchedRequestData.meta!.transactionManagerMeta.encryptionMethod,
388-
'ecies-aes256-cbc',
388+
'ecies-aes256-gcm',
389389
);
390390
assert.equal(fetchedRequestData.state, Types.RequestLogic.STATE.CREATED);
391391

@@ -449,7 +449,7 @@ describe('Request client using a request node', () => {
449449

450450
assert.equal(
451451
plainRequestData.meta!.transactionManagerMeta!.encryptionMethod,
452-
'ecies-aes256-cbc',
452+
'ecies-aes256-gcm',
453453
);
454454
assert.isNull(plainRequestData.meta!.transactionManagerMeta.ignoredTransactions![0]);
455455
assert.equal(
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { EncryptionTypes, MultiFormatTypes } from '@requestnetwork/types';
2+
3+
import SerializableMultiFormat from '../serializable-multi-format';
4+
5+
/**
6+
* Class to serialize and deserialize multi-format AES-256-GCM encrypted data
7+
*/
8+
export default class Aes256GcmMultiFormat extends SerializableMultiFormat {
9+
constructor() {
10+
super(MultiFormatTypes.prefix.AES256_GCM_ENCRYPTED, EncryptionTypes.METHOD.AES256_GCM);
11+
}
12+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import GroupMultiFormat from '../group-multi-format';
22
import Aes256Cbc from './aes256-cbc-format';
3+
import Aes256Gcm from './aes256-gcm-format';
34
import Ecies from './ecies-format';
45

56
// group all the multi-format concerning the encryption
6-
const group = new GroupMultiFormat([new Aes256Cbc(), new Ecies()]);
7+
const group = new GroupMultiFormat([new Aes256Cbc(), new Ecies(), new Aes256Gcm()]);
78
export default group;

packages/request-client.js/test/index.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ describe('index', () => {
985985
const requestData = requestFromId.getData();
986986
expect(requestData.meta).to.not.be.null;
987987
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
988-
'ecies-aes256-cbc',
988+
'ecies-aes256-gcm',
989989
);
990990
});
991991

@@ -1032,7 +1032,7 @@ describe('index', () => {
10321032
const requestData = requestsFromTopic[0].getData();
10331033
expect(requestData.meta).to.not.be.null;
10341034
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
1035-
'ecies-aes256-cbc',
1035+
'ecies-aes256-gcm',
10361036
);
10371037
});
10381038

@@ -1076,7 +1076,7 @@ describe('index', () => {
10761076
const requestData = req.getData();
10771077
expect(requestData.meta).to.not.be.null;
10781078
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
1079-
'ecies-aes256-cbc',
1079+
'ecies-aes256-gcm',
10801080
);
10811081
});
10821082
});
@@ -1104,7 +1104,7 @@ describe('index', () => {
11041104
const requestData = requestFromIdentity[0].getData();
11051105
expect(requestData.meta).to.not.be.null;
11061106
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
1107-
'ecies-aes256-cbc',
1107+
'ecies-aes256-gcm',
11081108
);
11091109
});
11101110

@@ -1129,7 +1129,7 @@ describe('index', () => {
11291129
const requestData = fetchedRequest.getData();
11301130
expect(requestData.meta).to.not.be.null;
11311131
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
1132-
'ecies-aes256-cbc',
1132+
'ecies-aes256-gcm',
11331133
);
11341134

11351135
await new Promise((resolve): any => setTimeout(resolve, 150));
@@ -1167,7 +1167,7 @@ describe('index', () => {
11671167
const requestData = fetchedRequest.getData();
11681168
expect(requestData.meta).to.not.be.null;
11691169
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
1170-
'ecies-aes256-cbc',
1170+
'ecies-aes256-gcm',
11711171
);
11721172

11731173
clock.tick(150);
@@ -1199,7 +1199,7 @@ describe('index', () => {
11991199
const requestData = fetchedRequest.getData();
12001200
expect(requestData.meta).to.not.be.null;
12011201
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
1202-
'ecies-aes256-cbc',
1202+
'ecies-aes256-gcm',
12031203
);
12041204

12051205
clock.tick(150);
@@ -1245,7 +1245,7 @@ describe('index', () => {
12451245
const requestData = fetchedRequest.getData();
12461246
expect(requestData.meta).to.not.be.null;
12471247
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).to.equal(
1248-
'ecies-aes256-cbc',
1248+
'ecies-aes256-gcm',
12491249
);
12501250

12511251
const acceptResult = await fetchedRequest.accept(payerIdentity);

packages/transaction-manager/specs/encryption.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Parties can be added on an encrypted channel by any other parties.
3737
The encryption uses:
3838

3939
- asymmetric Elliptic Curve Integrated Encryption Scheme (ECIES)
40-
- symmetric AES-256-CBC encryption.
40+
- symmetric AES-256-GCM encryption.
4141

4242
The data are first encrypted by AES-256 with a generated key.
4343
This key is then encrypted for every other party with ECIES from their public key.
@@ -50,10 +50,10 @@ The encrypted data, the encrypted keys and a hash of the data are pushed on chai
5050

5151
| Property | Type | Description |
5252
| -------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------- |
53-
| **encryptedData** | String | First encrypted data of the channel in base64 |
53+
| **encryptedData** | String | First encrypted data of the channel in base64 |
5454
| **hash** | String | Normalized Keccak256 hash of the message before encryption |
5555
| **keys** | Object | AES-256 key encrypted with ECIES from the parties public keys, encoded in base64 and indexed by their multi-formatted identities |
56-
| **encryptionMethod** | String | Encryption method use for the channel _('ECIES-AES256' here)_ |
56+
| **encryptionMethod** | String | Encryption method use for the channel _('ECIES-AES256-GCM' here)_ |
5757

5858
The data are encrypted with the algorithm AES-256 from the channel key generated for this channel.
5959
The channel key generation must be cryptographically strong.
@@ -70,16 +70,16 @@ Example:
7070
"20af083f77f1ffd54218d91491afd06c9296eac3ce": "aYOGYgtlt0JkBoKjxkMpoQJbE7GXtTT6JrjA+NF0Bd6BxDLyn5+hFIDvHltMkGS7rpzR3RyEnDl+SncDJ+cCxLo9Od7ntqGNVdin6n7EJqilmY0AmxJpAIAOnCwK5C46zH4RE0g7vBv/+3Gx2uFKw2Dfhpy7olQ5NL6Krsb2qEnmW32R3wmv85uCE88uxmcDlo/OrS36X+jzOye+/ZR+kOE=",
7171
"20740fc87bd3f41d07d23a01dec90623ebc5fed9d6": "AKJaJONWml2moKwTGZCuXQMxBt014+6Sxo2rzXYBbgKV8peBo3RM6KrxvhIdnCtTwxu3CrlFrkfUm6VYoMsKPu5WhZMU1Wk2R+vYl7roJFCQsTqTN1Qkx0skBLhaSKwynzZY3BWyTZ5rf1+JPmi7g6fGB9VOUpv6EDlp9k1p2RZnsVc+fMYKMAWhMnSZ3gJQUVbHY2Jx0CiQX/N+PtpnTWM=",
7272
},
73-
"encryptionMethod": "ECIES-AES256-CBC"
73+
"encryptionMethod": "ECIES-AES256-GCM"
7474
}
7575
```
7676

7777
### Add encrypted data
7878

79-
| Property | Type | Description |
80-
| -------- | ------ | ---------------------------------------------------------- |
79+
| Property | Type | Description |
80+
| ----------------- | ------ | ---------------------------------------------------------- |
8181
| **encryptedData** | String | Encrypted data in base64 |
82-
| **hash** | String | Normalized Keccak256 hash of the message before encryption |
82+
| **hash** | String | Normalized Keccak256 hash of the message before encryption |
8383

8484
Example:
8585

packages/transaction-manager/src/transactions-factory.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ export default class TransactionsFactory {
3636
encryptionParams: EncryptionTypes.IEncryptionParameters[],
3737
): Promise<TransactionTypes.IPersistedTransaction> {
3838
// format encryption method property
39-
const encryptionMethod = `${EncryptionTypes.METHOD.ECIES}-${EncryptionTypes.METHOD.AES256_CBC}`;
39+
const encryptionMethod = `${EncryptionTypes.METHOD.ECIES}-${EncryptionTypes.METHOD.AES256_GCM}`;
4040

4141
// Generate a key for the AES encryption
4242
const symmetricKey: string = await Utils.crypto.generate32BufferKey();
4343

44-
// Encrypt the data with the key and the AES256-CBC algorithm
44+
// Encrypt the data with the key and the AES256-GCM algorithm
4545
const encryptedData: EncryptionTypes.IEncryptedData = await Utils.encryption.encrypt(data, {
4646
key: symmetricKey,
47-
method: EncryptionTypes.METHOD.AES256_CBC,
47+
method: EncryptionTypes.METHOD.AES256_GCM,
4848
});
4949

5050
// Compute the hash of the data
@@ -122,11 +122,11 @@ export default class TransactionsFactory {
122122
channelKey: EncryptionTypes.IEncryptionParameters,
123123
): Promise<TransactionTypes.IPersistedTransaction> {
124124
// check if the encryption method is the good one
125-
if (channelKey.method !== EncryptionTypes.METHOD.AES256_CBC) {
125+
if (channelKey.method !== EncryptionTypes.METHOD.AES256_GCM) {
126126
throw new Error(`encryption method not supported for the channel key: ${channelKey.method}`);
127127
}
128128

129-
// Encrypt the data with the key and the AES256-CBC algorithm
129+
// Encrypt the data with the key and the AES256-GCM algorithm
130130
const encryptedData: EncryptionTypes.IEncryptedData = await Utils.encryption.encrypt(
131131
data,
132132
channelKey,

packages/transaction-manager/src/transactions-parser.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,17 @@ export default class TransactionsParser {
110110
throw new Error(`No decryption provider given`);
111111
}
112112

113+
let channelKeyMethod: EncryptionTypes.METHOD;
113114
// Check the encryption method
114115
if (
115-
encryptionMethod !== `${EncryptionTypes.METHOD.ECIES}-${EncryptionTypes.METHOD.AES256_CBC}`
116+
encryptionMethod === `${EncryptionTypes.METHOD.ECIES}-${EncryptionTypes.METHOD.AES256_CBC}`
116117
) {
118+
channelKeyMethod = EncryptionTypes.METHOD.AES256_CBC;
119+
} else if (
120+
encryptionMethod === `${EncryptionTypes.METHOD.ECIES}-${EncryptionTypes.METHOD.AES256_GCM}`
121+
) {
122+
channelKeyMethod = EncryptionTypes.METHOD.AES256_GCM;
123+
} else {
117124
throw new Error(`Encryption method not supported: ${encryptionMethod}`);
118125
}
119126

@@ -157,7 +164,7 @@ export default class TransactionsParser {
157164
}
158165
return {
159166
key: channelKey,
160-
method: EncryptionTypes.METHOD.AES256_CBC,
167+
method: channelKeyMethod,
161168
};
162169
}
163170
}

0 commit comments

Comments
 (0)