1
0
mirror of https://github.com/rclone/rclone.git synced 2025-12-29 06:33:16 +00:00

crypt: add an "obfuscate" option for filename encryption.

This is a simple "rotate" of the filename, with each file having a rot
distance based on the filename.  We store the distance at the beginning
of the filename.  So a file called "go" would become "37.KS".

This is not a strong encryption of filenames, but it should stop automated
scanning tools from picking up on filename patterns.  As such it's an
intermediate between "off" and "standard".  The advantage is that it
allows for longer path segment names.

We use the nameKey as an additional input to calculate the obfuscation
distance.  This should mean that two different passwords will result
in two different keys

The obfuscation rotation works by splitting the ranges up and handle cases
  0-9
  A-Za-z
  0xA0-0xFF
  and anything greater in blocks of 256
This commit is contained in:
Stephen Harris
2017-03-12 14:14:36 -04:00
committed by Nick Craig-Wood
parent 37e1b20ec1
commit 6e003934fc
4 changed files with 247 additions and 3 deletions

View File

@@ -23,6 +23,7 @@ func TestNewNameEncryptionMode(t *testing.T) {
}{
{"off", NameEncryptionOff, ""},
{"standard", NameEncryptionStandard, ""},
{"obfuscate", NameEncryptionObfuscated, ""},
{"potato", NameEncryptionMode(0), "Unknown file name encryption mode \"potato\""},
} {
actual, actualErr := NewNameEncryptionMode(test.in)
@@ -38,7 +39,8 @@ func TestNewNameEncryptionMode(t *testing.T) {
func TestNewNameEncryptionModeString(t *testing.T) {
assert.Equal(t, NameEncryptionOff.String(), "off")
assert.Equal(t, NameEncryptionStandard.String(), "standard")
assert.Equal(t, NameEncryptionMode(2).String(), "Unknown mode #2")
assert.Equal(t, NameEncryptionObfuscated.String(), "obfuscate")
assert.Equal(t, NameEncryptionMode(3).String(), "Unknown mode #3")
}
func TestValidString(t *testing.T) {
@@ -219,6 +221,11 @@ func TestEncryptFileName(t *testing.T) {
// Now off mode
c, _ = newCipher(NameEncryptionOff, "", "")
assert.Equal(t, "1/12/123.bin", c.EncryptFileName("1/12/123"))
// Obfuscation mode
c, _ = newCipher(NameEncryptionObfuscated, "", "")
assert.Equal(t, "49.6/99.23/150.890/53.!!lipps", c.EncryptFileName("1/12/123/!hello"))
assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1"))
assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0"))
}
func TestDecryptFileName(t *testing.T) {
@@ -236,6 +243,10 @@ func TestDecryptFileName(t *testing.T) {
{NameEncryptionOff, "1/12/123.bin", "1/12/123", nil},
{NameEncryptionOff, "1/12/123.bix", "", ErrorNotAnEncryptedFile},
{NameEncryptionOff, ".bin", "", ErrorNotAnEncryptedFile},
{NameEncryptionObfuscated, "0.hello", "hello", nil},
{NameEncryptionObfuscated, "hello", "", ErrorNotAnEncryptedFile},
{NameEncryptionObfuscated, "161.\u00e4", "\u00a1", nil},
{NameEncryptionObfuscated, "160.\u03c2", "\u03a0", nil},
} {
c, _ := newCipher(test.mode, "", "")
actual, actualErr := c.DecryptFileName(test.in)
@@ -245,6 +256,23 @@ func TestDecryptFileName(t *testing.T) {
}
}
func TestEncDecMatches(t *testing.T) {
for _, test := range []struct {
mode NameEncryptionMode
in string
}{
{NameEncryptionStandard, "1/2/3/4"},
{NameEncryptionOff, "1/2/3/4"},
{NameEncryptionObfuscated, "1/2/3/4/!hello\u03a0"},
} {
c, _ := newCipher(test.mode, "", "")
out, err := c.DecryptFileName(c.EncryptFileName(test.in))
what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
assert.Equal(t, out, test.in, what)
assert.Equal(t, err, nil, what)
}
}
func TestEncryptDirName(t *testing.T) {
// First standard mode
c, _ := newCipher(NameEncryptionStandard, "", "")