Skip to content

Commit 370a8e2

Browse files
alolisAlexander Lolis
and
Alexander Lolis
authored
feat(rclone): Implement support for empty salts (#5)
* Implement support for empty salts If an empty string is used as a salt then it should be replaced with a default one as also done by rclone: https://github.com/rclone/rclone/blob/b9bd15a8c980c36f15dd9b90bc0c422e4020baec/backend/crypt/cipher.go#L175 The default salt that must be used can be found here: https://github.com/rclone/rclone/blob/b9bd15a8c980c36f15dd9b90bc0c422e4020baec/backend/crypt/cipher.go#L54 * Add test Co-authored-by: Alexander Lolis <alolis@rapiddot.com>
1 parent eb9aab4 commit 370a8e2

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

src/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export const fileHeaderSize = fileMagicSize + fileNonceSize;
99
export const blockHeaderSize = 16; // crypto_secretbox_BOXZEROBYTES
1010
export const blockDataSize = 64 * 1024;
1111
export const blockSize = blockHeaderSize + blockDataSize;
12+
export const defaultSalt = [0xa8, 0x0d, 0xf4, 0x3a, 0x8f, 0xbd, 0x03, 0x08, 0xa7, 0xca, 0xb8, 0x3e, 0x58, 0x1f, 0x86, 0xb1];

src/rclone.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
fileHeaderSize,
1010
blockHeaderSize,
1111
blockDataSize,
12-
blockSize
12+
blockSize,
13+
defaultSalt
1314
} from './constants';
1415

1516
function Rclone({ password, salt } = {}) {
@@ -50,7 +51,9 @@ export { Rclone };
5051
// pass and salt are still encrypted with the rclone config encryption
5152
function generateKeys(encPass, encSalt, callback) {
5253
const password = reveal(encPass);
53-
const salt = reveal(encSalt);
54+
const decryptedSalt = reveal(encSalt);
55+
const salt = decryptedSalt.length ? decryptedSalt : defaultSalt;
56+
5457
if (password.length === 0) {
5558
// Empty key for testing
5659
callback(

src/rclone.test.js

+21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Rclone } from './rclone';
2+
import {defaultSalt} from './constants';
3+
import PathCipher from './ciphers/PathCipher';
24

35
test('both password and salt must be passed', done => {
46
Rclone({
@@ -17,3 +19,22 @@ test('derive keys from password', done => {
1719
})
1820
.catch(err => done.fail(err));
1921
});
22+
23+
test('use default salt when empty', done => {
24+
// Generated encrypted string with the use of rclone and empty salt
25+
const rcloneEncryptedFileName = 'ecrk8fu3e0pk86td3r634nan08';
26+
const rcloneDecryptedFileName = 'encrypted_file'
27+
28+
Rclone({
29+
password: 'UmyLSdRHfew6aual28-ggx78qHqSfQ',
30+
salt: ''
31+
})
32+
.then(rclone => {
33+
const pathCipher = PathCipher(rclone);
34+
const decryptedString = pathCipher.decrypt(rcloneEncryptedFileName);
35+
36+
expect(decryptedString).toEqual(rcloneDecryptedFileName);
37+
done();
38+
})
39+
.catch(err => done.fail(err));
40+
});

0 commit comments

Comments
 (0)