MobileOrg / mobileorg

MobileOrg iPhone App
http://mobileorg.github.io
GNU General Public License v2.0
556 stars 69 forks source link

Not able to encrypt #203

Closed klprint closed 6 years ago

klprint commented 7 years ago

Hi, I am using Mobile-Org in combination with Dropbox. Since I am not very eager to store my agenda-file in clear-text in this service, I wanted to encrypt the synced files using mobile-orgs encryption feature. When I try to set it up on my iPhone and Mac (Sierra), I get it to work. But when I use customize-group --> org-mobile --> org-mobile-encryption-password and set org-mobile-use-encryption to non-nil the sync on my phone stops to work (yes, I also set the correct password here) and the only file displayed on the iPhone says: "Unable to encrypt file, please check your password".

I double checked the password and it is correct. I deleted the whole folder from dropbox and reinitialized the whole process, but still no luck.. Any suggestions?

mgmart commented 7 years ago

Although I do not understand the whole issue, it might help to know which version of MobileOrg, Org and iOS are used.

frapples commented 7 years ago

Me, too. I feel this bug(https://github.com/MobileOrg/mobileorg/issues/189) still exists.

When I set a password using mobileorg, there are bugs. This prompt ”Unable to encrypt file, please check your password“ rather than the last as prompted ”Unable to detect file encoding, please re-save this file using UTF-8.“。

pekp commented 6 years ago

I am facing the same issue. I am have MobileOrg 1.74 on iOS 11. Everything works, as long as I don't set a password in the MobileOrg settings, and in my emacs config.

The scenario that gives me trouble is as follows:

org-mobile-push calls the following function from org-mobile.el:

(defun org-mobile-encrypt-file (infile outfile)
  "Encrypt INFILE to OUTFILE, using `org-mobile-encryption-password'."
  (shell-command
   (format "openssl enc -aes-256-cbc -salt -pass %s -in %s -out %s"
       (shell-quote-argument (concat "pass:"
                     (org-mobile-encryption-password)))
       (shell-quote-argument (expand-file-name infile))
       (shell-quote-argument (expand-file-name outfile)))))

We see that the openssl command is called, and the password "a" is passed as "pass:a".

On the command line I can succesfully decrypt the file example.org in my org-mobile stage with:

$ openssl enc -d -aes-256-cbc -salt -pass 'pass:a' -in example.org -out example.org.decrypted

Alright. I can't find the string "pass:" anywhere in the MobileOrg source code. Is this somehow appended by an external library? Setting the password to "pass:a" in Mobile Org doesn't help.

Let's examine where the error message in Mobile Org comes from:

NSString *ReadPossiblyEncryptedFile(NSString *filename, NSString **error) {
    *error = nil;

    NSMutableData *data = [NSMutableData dataWithContentsOfFile:filename];
    if (!data) {
        *error = @"Unable to open file";
        return nil;
    }

    char buffer[16];
    [data getBytes:buffer length:8];        
    if (!strncmp((const char*)buffer, "Salted__", 8)) {
        NSData *decryptedData = [data AES256DecryptWithKey:[[Settings instance] encryptionPassword]];

        if (decryptedData) {

// We seem to have decrypted data at this point! Hurray! Why don't // we just return it, and call it a day?

            if ([decryptedData length] > 0) {

// Instead...

                NSString *tmpFileName = FileWithName(@"decrypted-file.org");
                [[NSFileManager defaultManager] createFileAtPath:tmpFileName contents:decryptedData attributes:nil];              

                NSStringEncoding encoding;
                NSError *e;
                NSString *ret = [NSString stringWithContentsOfFile:tmpFileName usedEncoding:&encoding error:&e];

// ... we try to dump the decrypted data to "decrypted-file.org". // Where is the sense in that?

                if( ret == nil) {

// Ooops. This fails. And gives a non-sensical error message. Where // is the encryption that the error message talks about?

                  *error = @"Unable to encrypt file, please check your password";
                  return nil;
                }

// Immediatelly after that we delete "decrypted-file.org"...

                DeleteFile(FileWithName(@"decrypted-file.org"));

               return ret;
            } else {
                return @"";
            }
        } else {
            *error = @"Unable to decrypt file";
            return nil;
        }      
    } else {
        NSStringEncoding encoding;
        NSError *e;
        return [NSString stringWithContentsOfFile:filename usedEncoding:&encoding error:&e];
    }
}

I don't know much about Objective C and I don't know much about cryptography, but the entire crypto code of Mobile Org looks exteremly dubious. I know that it is "just" decryption, but it would be great if we could find an expert to do an audit.

I don't feel comfortable storing my unencrypted personal org files somewhere on a server. Who knows where they will wind up? A server misconfiguration I can't do anything about is enough to expose them to the Internet, where they will be archived and indexed forever.

This is what I found about the "openssl enc" command:

https://stackoverflow.com/questions/28247821/openssl-vs-gpg-for-encrypting-off-site-backups

I don't know how severe these issues really are, but it would be good, if somebody more knowledgable about this subject could weigh in.

mgmart commented 6 years ago

Thanks for the analysis @pekp which helped me to get to the bottom of this issue.

TLDR: To keep the encryption methods used by Org Mode and MobileOrg in sync please update Org Mode to a version >= 9.0.10

OpenSSL changed the default for symmetrical encryption to SHA256. Due to that MD5 is not set as the default for hashing anymore.

openssl enc -d -aes-256-cbc -salt -pass 'pass:a' -in example.org -out example.org.decrypted

This is fixed in f203d37 which is released in Org Mode 9.0.10 to

openssl enc -md md5 -aes-256-cbc -salt -pass %s -in %s -out %s

the password "a" is passed as "pass:a".

OpenSSL supports different methods to pass the password where passis the method to provide the password directly. MobileOrg has the AES256 algorithm implemented and does not use OpenSSL.

We seem to have decrypted data at this point! Hurray! Why don't we just return it, and call it a day?

Good question. The extra file operations only have an impact on performance not on security. But this is worth a some deeper analysis I think.

but the entire crypto code of Mobile Org looks exteremly dubious.

I wouldn't say that. AES256 is fine from my perspective. Any changes there must be initiated from Org Mode, though.

mgmart commented 6 years ago

Seems to be solved

keeper-dev commented 3 years ago

I seem to have the same problem: Using MobileOrg 1.7.5 and Org Mode 9.4.4 iPadOS 14.6

When I use org-mobile-push, everything is staged and the files are encrypted. When I counter-check using: openssl enc -md md5 -aes-256-cbc -salt -pass "pass:<myPassword>" -d -in example.org -out ~/example.org.decrypted I get the correct decrypted file.

When I try to sync the app however I keep getting:

Error: Unable to encrypt file, please check your password

Any advice?

keeper-dev commented 3 years ago

@mgmart: Can you reopen this issue?