|
I like the ability to sync a backup to Dropbox, but if I lose my phone I want to be able to decrypt and read my backup without Pocket, since there is no telling when I'll be able to get another instance running with the backup imported. I've done a little poking around, but I had some questions related to being able to decrypt the database *without* having Pocket do it for me.
1a. How do "hash.txt" and "wallet.db" relate to each other? 1b. What is stored in "hash.txt"? 2a. It appears that "wallet.db" stores the metadata of what groups and fields we have, at least. Does it also store the entries and information inside each field? 2b. Is all of the user-editable information (group names, field names, etc.) encrypted? 2c. At what point is the encryption done? Do you simply encrypt the data being stored in a row, or is there a "blob" you pull from a bare-bones database which decrypts into more formatted text? 3. What is the encryption algorithm and parameters used on the backup? |
|
Administrator
|
1a. wallet.db is a sqlite db file which contains encrypted strings.
1b. 5 lines: salted password hash version new encryption method password salt encryption salt I probably should have stored this data in the database too... 2a. yes 2b. all fields, values, titles, notes, etc are encrypted. 2c. I encrypt data being stored in a row 3. Used on the backup? Not sure what you mean here... When you export to SDCard? Sync with Dropbox? |
|
For #3, what is the actual algorithm being used to encrypt the strings? AES-256 in CBC mode? Is the encryption salt the initialization vector passed to the algorithm?
|
|
Administrator
|
Yep. AES/CBC/PKCS5Padding
No. IV is concatenated to the string in the db. Password salt is for one way hash. Encryption salt is for the SecretKey. Are you trying to decode your data? |
|
Administrator
|
If you want the code for encryption decryption send me an email and I will send it to you.
|
|
In reply to this post by timothyjc
Yeah, the end result is to be able to decrypt and read the automatically-sync'ed file, so I don't have to manually export and encrypt my own backups. That way, if I lose my phone, I still have all the data until I get a new phone and install Pocket again.
|
|
I am also interested in getting decryption working I have tried unsucessfully this Ruby script c = OpenSSL::Cipher::Cipher.new("aes-256-cbc") c.decrypt c.key = key = Digest::SHA1.hexdigest("MYMASTERKEY") c.iv = iv = "F2A132C1F57970EF1C69F6741B501EF0" e = "9A93437B35EA244F95F78B7DAD6CB536" puts "encrypted: #{e}\n" d = c.update(e) d << c.final puts "decrypted: #{d}\n" I am trying to decrypt: F2A132C1F57970EF1C69F6741B501EF09A93437B35EA244F95F78B7DAD6CB536 Even if you dont know Ruby I think you will see what I am doing wrong. I am not interested in the encryption side. For now I just want to have readonly access to the DB. |
|
Administrator
|
package com.citc.pocket.crypto;
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; public class AdvancedCrypto implements ICrypto { public static final String PROVIDER = "BC"; public static final int SALT_LENGTH = 20; public static final int IV_LENGTH = 16; public static final int PBE_ITERATION_COUNT = 100; private static final String RANDOM_ALGORITHM = "SHA1PRNG"; private static final String HASH_ALGORITHM = "SHA-512"; private static final String PBE_ALGORITHM = "PBEWithSHA256And256BitAES-CBC-BC"; private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String SECRET_KEY_ALGORITHM = "AES"; public String encrypt(SecretKey secret, String cleartext) throws CryptoException { try { byte[] iv = generateIv(); String ivHex = HexEncoder.toHex(iv); IvParameterSpec ivspec = new IvParameterSpec(iv); Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM, PROVIDER); encryptionCipher.init(Cipher.ENCRYPT_MODE, secret, ivspec); byte[] encryptedText = encryptionCipher.doFinal(cleartext.getBytes("UTF-8")); String encryptedHex = HexEncoder.toHex(encryptedText); return ivHex + encryptedHex; } catch (Exception e) { throw new CryptoException("Unable to encrypt", e); } } public String decrypt(SecretKey secret, String encrypted) throws CryptoException { try { Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM, PROVIDER); String ivHex = encrypted.substring(0, IV_LENGTH * 2); String encryptedHex = encrypted.substring(IV_LENGTH * 2); IvParameterSpec ivspec = new IvParameterSpec(HexEncoder.toByte(ivHex)); decryptionCipher.init(Cipher.DECRYPT_MODE, secret, ivspec); byte[] decryptedText = decryptionCipher.doFinal(HexEncoder.toByte(encryptedHex)); String decrypted = new String(decryptedText, "UTF-8"); return decrypted; } catch (Exception e) { throw new CryptoException("Unable to decrypt", e); } } public SecretKey getSecretKey(String password, String salt) throws CryptoException { try { PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), HexEncoder.toByte(salt), PBE_ITERATION_COUNT, 256); SecretKeyFactory factory = SecretKeyFactory.getInstance(PBE_ALGORITHM, PROVIDER); SecretKey tmp = factory.generateSecret(pbeKeySpec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), SECRET_KEY_ALGORITHM); return secret; } catch (Exception e) { throw new CryptoException("Unable to get secret key", e); } } public String getHash(String password, String salt) throws CryptoException { try { String input = password + salt; MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM, PROVIDER); byte[] out = md.digest(input.getBytes("UTF-8")); return HexEncoder.toHex(out); } catch (Exception e) { throw new CryptoException("Unable to get hash", e); } } public String generateSalt() throws CryptoException { try { SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM); byte[] salt = new byte[SALT_LENGTH]; random.nextBytes(salt); String saltHex = HexEncoder.toHex(salt); return saltHex; } catch (Exception e) { throw new CryptoException("Unable to generate salt", e); } } private byte[] generateIv() throws NoSuchAlgorithmException, NoSuchProviderException { SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM); byte[] iv = new byte[IV_LENGTH]; random.nextBytes(iv); return iv; } } |
|
Nice implementation of the encryption.
But you should probably replace the sha(password+salt) for masterkey with BCrypt hash since the simple sha hash is easy enough to brute force today (even with no rainbow tables). See http://codahale.com/how-to-safely-store-a-password/ for more info |
|
i use dropbox but when i try and download my file on my desktop, it says its a db file. how do i open the file , ive used word, texteditor, wordpad, etc...
|
|
In reply to this post by timothyjc
Hi please sent me the full code,i m new for Encryption & Decryption.so i Deployed it into the android..
my email id: amit4397@gmail.com |
| Powered by Nabble | Edit this page |
