I wrote this program,
https://github.com/genjix/sekureco/blob/master/sekurecoTogether with a cloud backup service (see www),
https://github.com/genjix/sekurecoI need someone to vet the security by me explaining what it does. I also need to clean up the code (comments, organisation, consistent naming), but for now it encrypts / backs up to server.
For integrating inside a bitcoin client.
./sekureco is a command line tool you can run with help instructions. See README also.
It works by using symmetric encryption for the wallet file (AES) and encrypting the AES key using an asymmetric encryption scheme (RSA).
For the server backup side, you upload (once only) your RSA keypair + encrypted AES key. The server responds with a 40 character long random ID code which you then use to upload your encrypted wallets. If the client wishes to backup their wallet they need the ID to download the latest version. If the user correctly enters the pass to the RSA keypair they can download the keys or ID (which can be used for fetching the encrypted wallets or uploading new versions). If they guess the pass incorrectly then the restore functionality for that account is locked for 10 hours.
I'm very interested in this feature...if you upload the RSA key pair and the encrypted AES key, wouldn't the server then have everything necessary to decrypt the wallet? That wouldn't be good. Here's what I think I would do:
First, I think support in the official client for a wallet backup is an absolute must have. From a user perspective, they would fire up the client, enter info once for a wallet backup service provider, all the encryption would be done in the official client (only strongly encrypted wallets are ever sent to the backup service provider). The user should only have to enter a domain name for the backup service of their choosing (I'll leave the design for billing out of this post for now...mainly because I would hope this service would be offered for free initially while bitcoin is gaining in popularity...but also because I haven't given it any thought). Once the user enters the domain name for the service of their choice, it'll contact the service and get some unique id for the backup (this id would be used for recovery and the user should be instructed to keep that id in safe location in case they ever need to access the backup for recovery purposes). I suggest just using an id so that the service doesn't have to implement any account creation and such and the user doesn't have to go through that process (however, another alternative would be to use a users email address and doing email confirmation...that would minimize the risk of a user forgetting an assigned backup id).
Now for wallet encryption. I would ask the user for a password and enforce some basic minimum entropy and password strength. You then take the password and apply a crypto hash with a salt (i.e. sha256) to yield a derived password of say 24 bytes in length. This is the key that will be used to encrypt the wallet with AES-256. The encrypted wallet is transmitted to the server using SSL (which uses public key crypto). The server could encrypt once more for storage on disk (in case someone gains access to the files on the server).
The client would automatically backup to the server every time a new bitcoin address is created (prompting for the user's password if they haven't already entered it, but remembering the server and id/email details). The user's password would never be stored on disk.
Recovery would require the server assigned wallet id (or email address) to retrieve the backup wallet and the user would need to support their password (which would be hashed to get the AES-256 key for decryption).
Note: I do realize that hashing their password with a salt doesn't really add much additional protection against a brute force password attack if the attacker knows the salt and the hash algorithm (note, for a bit of extra security, the salt could be obtained from the server and be different for each account...an attacker would need to know what salt generation method the server was using). If the attacker doesn't know the hash algorithm or salt, then the hash ensures a longer, and hence more secure, encryption key.
For even more security, the user's password could also be hashed on the client a second time (different salt) and that hash used for authenticating the user with the service such that someone else couldn't obtain download access to a user's encrypted wallet (keeping an encrypted wallet out of untrusted hands being one additional protection against a brute force attack).
One possibility I thought about, but discarded was to use GPG auth for authentication with the service and for securely storing a long, generated AES key on the client machine. However, this has the disadvantage of relying on the local storage to keep the keys necessary for authentication and decryption (and then you would need a backup solution for this file as well!!!).
Note, the locally stored wallet should also be AES-256 encrypted on disk...the same password (with hashing and salting) could be used for the encryption key. This would enable the user to enter one password on startup to decrypt the local wallet...and hash into a key for encrypting the backup. The user's password would only be in memory temporarily for generating these hashes (thus reducing the risk of stealing this password out of memory...though the hash used for backup encryption would still be in memory).