Skip to content

Commit 500a724

Browse files
authored
fix: Encryption channel use multi-format for identity instead of hash (#501)
**Transaction-Manager**: * Use multi-format instead of hashes for identity keys in the encryption
1 parent 7100895 commit 500a724

File tree

5 files changed

+61
-25
lines changed

5 files changed

+61
-25
lines changed

packages/transaction-manager/specs/encryption.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ The encrypted data, the encrypted keys and a hash of the data are pushed on chai
4848

4949
### Create an encrypted channel
5050

51-
| Property | Type | Description |
52-
| -------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------- |
53-
| **data** | String | First encrypted data of the channel in base64 |
54-
| **hash** | String | Normalized Keccak256 hash of the message before encryption |
55-
| **keys** | Object | AES-256 key encrypted with ECIES from the parties public keys, encoded in base64 and indexed by the hash of their identities |
56-
| **encryptionMethod** | String | Encryption method use for the channel _('ECIES-AES256' here)_ |
51+
| Property | Type | Description |
52+
| -------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------- |
53+
| **data** | String | First encrypted data of the channel in base64 |
54+
| **hash** | String | Normalized Keccak256 hash of the message before encryption |
55+
| **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)_ |
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.
@@ -67,8 +67,8 @@ Example:
6767
"hash": "01865ea95812388a93162b560e01c5680f12966492dfbad8a9a104e1e79f6665fc",
6868
"keys":
6969
{
70-
"014e90cd5a599a1ac02d55d8af16655d4ae90d82642c6a8ef2fe2341a608053982": "aYOGYgtlt0JkBoKjxkMpoQJbE7GXtTT6JrjA+NF0Bd6BxDLyn5+hFIDvHltMkGS7rpzR3RyEnDl+SncDJ+cCxLo9Od7ntqGNVdin6n7EJqilmY0AmxJpAIAOnCwK5C46zH4RE0g7vBv/+3Gx2uFKw2Dfhpy7olQ5NL6Krsb2qEnmW32R3wmv85uCE88uxmcDlo/OrS36X+jzOye+/ZR+kOE=",
71-
"01f17f52151ebef6c7334fad080c5704d77216b732f6c7334fad08072117f341a6": "AKJaJONWml2moKwTGZCuXQMxBt014+6Sxo2rzXYBbgKV8peBo3RM6KrxvhIdnCtTwxu3CrlFrkfUm6VYoMsKPu5WhZMU1Wk2R+vYl7roJFCQsTqTN1Qkx0skBLhaSKwynzZY3BWyTZ5rf1+JPmi7g6fGB9VOUpv6EDlp9k1p2RZnsVc+fMYKMAWhMnSZ3gJQUVbHY2Jx0CiQX/N+PtpnTWM=",
70+
"20af083f77f1ffd54218d91491afd06c9296eac3ce": "aYOGYgtlt0JkBoKjxkMpoQJbE7GXtTT6JrjA+NF0Bd6BxDLyn5+hFIDvHltMkGS7rpzR3RyEnDl+SncDJ+cCxLo9Od7ntqGNVdin6n7EJqilmY0AmxJpAIAOnCwK5C46zH4RE0g7vBv/+3Gx2uFKw2Dfhpy7olQ5NL6Krsb2qEnmW32R3wmv85uCE88uxmcDlo/OrS36X+jzOye+/ZR+kOE=",
71+
"20740fc87bd3f41d07d23a01dec90623ebc5fed9d6": "AKJaJONWml2moKwTGZCuXQMxBt014+6Sxo2rzXYBbgKV8peBo3RM6KrxvhIdnCtTwxu3CrlFrkfUm6VYoMsKPu5WhZMU1Wk2R+vYl7roJFCQsTqTN1Qkx0skBLhaSKwynzZY3BWyTZ5rf1+JPmi7g6fGB9VOUpv6EDlp9k1p2RZnsVc+fMYKMAWhMnSZ3gJQUVbHY2Jx0CiQX/N+PtpnTWM=",
7272
},
7373
"encryptionMethod": "ECIES-AES256-CBC"
7474
}
@@ -92,16 +92,16 @@ Example:
9292

9393
### Add new public keys
9494

95-
| Property | Type | Description |
96-
| -------- | ------ | ------------------------------------------------------------------------------------------------- |
97-
| **keys** | Object | AES-256 key encrypted with ECIES from the new public keys indexed by the hash of their identities |
95+
| Property | Type | Description |
96+
| -------- | ------ | ----------------------------------------------------------------------------------------------------- |
97+
| **keys** | Object | AES-256 key encrypted with ECIES from the new public keys indexed by their multi-formatted identities |
9898

9999
Example:
100100

101101
```JSON
102102
{
103103
"keys": {
104-
"01c5fdf4076b8f3a5357c5e395ab970b5b54098fefa65a761e8df9792af3f398a": "OXdF4wZshE3+FM49ojErrgJIzqCx4r0DDj0bqof1yQJ7Kmz3zTaYh1xauD/Pq6HO1TJ3h+g4ca9DNzy2m2j7Q2RkqppeDkh4zsSyQ0eEN1dYLjfHqOisWelZ5l4hAH7+0LM8FHTCpKFJ1kSSHuALubYzbA+uO17eEr2dgzR3WaWDUhVn/uMYFwws3mHto41W4FWDGW+AWxIowhc3HrqsZRE=",
104+
"20818b6337657a23f58581715fc610577292e521d0": "OXdF4wZshE3+FM49ojErrgJIzqCx4r0DDj0bqof1yQJ7Kmz3zTaYh1xauD/Pq6HO1TJ3h+g4ca9DNzy2m2j7Q2RkqppeDkh4zsSyQ0eEN1dYLjfHqOisWelZ5l4hAH7+0LM8FHTCpKFJ1kSSHuALubYzbA+uO17eEr2dgzR3WaWDUhVn/uMYFwws3mHto41W4FWDGW+AWxIowhc3HrqsZRE=",
105105
}
106106
}
107107
```

packages/transaction-manager/src/transaction.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,25 @@ async function createEncryptedTransaction(
5959
const encryptedKeyAndIdentityHashesPromises = encryptionParams.map(
6060
async (
6161
encryptionParam: EncryptionTypes.IEncryptionParameters,
62-
): Promise<{ encryptedKey: string; hashedIdentity: string }> => {
62+
): Promise<{ encryptedKey: string; multiFormattedIdentity: string }> => {
6363
const encryptedKey = await Utils.encryption.encrypt(symmetricKey, encryptionParam);
6464
const identityEncryption = Utils.encryption.getIdentityFromEncryptionParams(encryptionParam);
65-
const hashedIdentity = Utils.crypto.normalizeKeccak256Hash(identityEncryption);
65+
const multiFormattedIdentity = Utils.multiFormat.formatIdentityEthereumAddress(
66+
identityEncryption.value,
67+
);
6668

67-
return { encryptedKey, hashedIdentity };
69+
return { encryptedKey, multiFormattedIdentity };
6870
},
6971
);
7072
const encryptedKeyAndIdentityHashes = await Promise.all(encryptedKeyAndIdentityHashesPromises);
7173

72-
// Create the encrypted keys object - Encrypted keys indexed by identity hash
74+
// Create the encrypted keys object - Encrypted keys indexed by identity multi-format
7375
const keys = encryptedKeyAndIdentityHashes.reduce(
74-
(allKeys: any, keyAndHash: { encryptedKey: string; hashedIdentity: string }): Promise<any> => {
75-
allKeys[keyAndHash.hashedIdentity] = keyAndHash.encryptedKey;
76+
(
77+
allKeys: any,
78+
keyAndHash: { encryptedKey: string; multiFormattedIdentity: string },
79+
): Promise<any> => {
80+
allKeys[keyAndHash.multiFormattedIdentity] = keyAndHash.encryptedKey;
7681
return allKeys;
7782
},
7883
{},

packages/transaction-manager/test/unit/transaction-test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ describe('transaction', () => {
4848

4949
expect(Object.keys(encryptedTx.keys || {}).length, 'keys not right').to.deep.equal(3);
5050
expect(Object.keys(encryptedTx.keys || {}), 'keys not right').to.deep.equal([
51-
Utils.crypto.normalizeKeccak256Hash(TestData.idRaw1.identity),
52-
Utils.crypto.normalizeKeccak256Hash(TestData.idRaw2.identity),
53-
Utils.crypto.normalizeKeccak256Hash(TestData.idRaw3.identity),
51+
Utils.multiFormat.formatIdentityEthereumAddress(TestData.idRaw1.identity.value),
52+
Utils.multiFormat.formatIdentityEthereumAddress(TestData.idRaw2.identity.value),
53+
Utils.multiFormat.formatIdentityEthereumAddress(TestData.idRaw3.identity.value),
5454
]);
5555

5656
expect(

packages/types/src/multi-format-types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ export enum prefix {
77
ECIES_ENCRYPTED = '02',
88
/** AES256-CBC encrypted data */
99
AES256_CBC_ENCRYPTED = '03',
10+
11+
/** Identity Ethereum address */
12+
IDENTITY_ETHEREUM_ADDRESS = '20',
1013
}
1114

1215
/** Length of a formatted normalized Keccak256 hash (prefix + hash = 2 + 64 = 66) (no 0x expected) */
1316
export const FORMAT_NORMALIZE_KECCAK256_HASH_LENGTH = 66;
17+
18+
/** Length of a formatted ethereum address identity (prefix + address = 2 + 40 = 42) (no 0x expected) */
19+
export const FORMAT_IDENTITY_ETHEREUM_ADDRESS_LENGTH = 42;

packages/utils/src/multi-format.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import { MultiFormatTypes } from '@requestnetwork/types';
66
export default {
77
formatAes256cbcEncryption,
88
formatEciesEncryption,
9+
formatIdentityEthereumAddress,
910
formatKeccak256Hash,
1011
formatPlainText,
1112
isAes256cbcEncryption,
1213
isEciesEncryption,
14+
isIdentityEthereumAddress,
1315
isKeccak256Hash,
1416
isPlainText,
1517
removePadding,
@@ -19,7 +21,7 @@ export default {
1921
* Formats a plain text
2022
*
2123
* @param data data to format in plain text
22-
* @returns the data with the right prefix ('00')
24+
* @returns the data with the right prefix (MultiFormatTypes.prefix.PLAIN_TEXT)
2325
*/
2426
function formatPlainText(data: string): string {
2527
return `${MultiFormatTypes.prefix.PLAIN_TEXT}${data}`;
@@ -39,7 +41,7 @@ function isPlainText(formattedData: string): boolean {
3941
* Transforms a keccak256 to a multi-format keccak256
4042
*
4143
* @param hash to format
42-
* @returns format the hash replacing the prefix '0x' by '01'
44+
* @returns format the hash replacing the prefix '0x' by MultiFormatTypes.prefix.NORMALIZE_KECCAK256_HASH
4345
*/
4446
function formatKeccak256Hash(hash: string): string {
4547
if (hash.length !== MultiFormatTypes.FORMAT_NORMALIZE_KECCAK256_HASH_LENGTH) {
@@ -65,7 +67,7 @@ function isKeccak256Hash(formattedData: string): boolean {
6567
* Transforms an ECIES encrypted data to a multi-format
6668
*
6769
* @param encryptedData encrypted data to format
68-
* @returns format the encrypted data adding the prefix '02'
70+
* @returns format the encrypted data adding the prefix MultiFormatTypes.prefix.ECIES_ENCRYPTED
6971
*/
7072
function formatEciesEncryption(encryptedData: string): string {
7173
return `${MultiFormatTypes.prefix.ECIES_ENCRYPTED}${encryptedData}`;
@@ -85,7 +87,7 @@ function isEciesEncryption(formattedData: string): boolean {
8587
* Transforms an AES256-cbc encrypted data to a multi-format
8688
*
8789
* @param encryptedData encrypted data to format
88-
* @returns format the encrypted data adding the prefix '03'
90+
* @returns format the encrypted data adding the prefix MultiFormatTypes.prefix.AES256_CBC_ENCRYPTED
8991
*/
9092
function formatAes256cbcEncryption(encryptedData: string): string {
9193
return `${MultiFormatTypes.prefix.AES256_CBC_ENCRYPTED}${encryptedData}`;
@@ -101,6 +103,29 @@ function isAes256cbcEncryption(formattedData: string): boolean {
101103
return formattedData.slice(0, 2) === MultiFormatTypes.prefix.AES256_CBC_ENCRYPTED;
102104
}
103105

106+
/**
107+
* Transforms an ethereum address to a multi-format
108+
*
109+
* @param ethereumAddress ethereum address to format
110+
* @returns format the encrypted data adding the prefix MultiFormatTypes.prefix.IDENTITY_ETHEREUM_ADDRESS
111+
*/
112+
function formatIdentityEthereumAddress(ethereumAddress: string): string {
113+
return `${MultiFormatTypes.prefix.IDENTITY_ETHEREUM_ADDRESS}${ethereumAddress.slice(2)}`;
114+
}
115+
116+
/**
117+
* Checks if a formatted data is an ethereum address identity
118+
*
119+
* @param formattedData the formatted data to check
120+
* @returns true if follow the format, false otherwise
121+
*/
122+
function isIdentityEthereumAddress(formattedData: string): boolean {
123+
return (
124+
formattedData.slice(0, 2) === MultiFormatTypes.prefix.IDENTITY_ETHEREUM_ADDRESS &&
125+
formattedData.length === MultiFormatTypes.FORMAT_IDENTITY_ETHEREUM_ADDRESS_LENGTH
126+
);
127+
}
128+
104129
/**
105130
* Removes padding of a multi-format
106131
*

0 commit comments

Comments
 (0)