Cryptocurrency wallet mnemonic seed phrase - ethereum

I'm working on a crypto wallet app and I need help with these following questions;
when creating a new wallet, how do the Blockchain network check if a certain mnemonic seed phrase has been used before for creating another wallet?
is it ever possible for two independent wallets to have the same mnemonic seed phrase?. If Yes, what's the implication? If No, why?
tips on security measures to observe when providing mnemonic seed phrases for crypto wallets?
Thanks

 when creating a new wallet, how do the Blockchain network check if a certain mnemonic seed phrase has been used before for creating another wallet?
The network doesn't check previous usage of the seed.
If you're importing a seed into a wallet and the wallet automatically imports used accounts generated from this seed - this check is performed on the wallet level.
It keeps iterating the index number in the derivation path - each iteration results in one account. The wallet checks if the account has > 0 sent / received transactions. If there are transactions on the account, the account is imported to the wallet. If there are no transactions on the account, the loop stops.
Sometimes the import also already contains the number of accounts - then the check of number of transactions is not required.
is it ever possible for two independent wallets to have the same mnemonic seed phrase?. If Yes, what's the implication? If No, why?
Theoretically possible.
Bug in implementation of generating randomness. If both wallets decide that "random number is 6", then the same "random" seed is generated on both.
Statistical probability that both generate truly random seed and the seed is the same, is very very very low. Practically impossible even if the machine was trying to generate seeds over and over for trillions of years until it finds the same seed. But statistically, the probability is non-zero.
tips on security measures to observe when providing mnemonic seed phrases for crypto wallets?
If possible, use input from the user to help generate the seed. For example some apps collect user mouse movements (presumably unique for each user / session) when generating the seed.
Encryption. Keep the raw data stored in an encrypted form, with access control - e.g. short-lived or one-time-access tokens.

Related

Store JSON documents in Hyperledger Fabric

I need a private blockchain system in which I would store complex data structures such as JSON documents.
The idea is that every transaction is a JSON document (with potentially various schema).
Hyperleadger Fabric seems to be a great fit since it can run using CouchDB. Although, from my understanding (please correct me if I'm wrong), in Fabric, CouchDB is supposed to be used as a state database that contains the latest state of the blockchain. Furthermore, data stored in CouchDB is not actually part of the blockchain which means it doesn't support Byzantine fault tolerance. So I could only use that system in a trusted consensus. If that is the case, then the use of a Blockchain over a distributed database system becomes irrelevant altogether.
Am I missing something?
Could I store my heterogeneous JSON documents in the ledger via transactions to benefit byzantine fault tolerance? If that is the case will it be possible to query the blockchain at this point?
A blockchain ledger consists of two distinct, though related, parts – a world state and a blockchain.
Firstly, there’s a world state – a database that holds the current values of a set of ledger states. The world state makes it easy for a program to get the current value of these states, rather than having to calculate them by traversing the entire transaction log. Ledger states are, by default, expressed as key-value pairs, though we’ll see later that Hyperledger Fabric provides flexibility in this regard. The world state can change frequently, as states can be created, updated and deleted.
Secondly, there’s a blockchain – a transaction log that records all the changes that determine the world state. Transactions are collected inside blocks that are appended to the blockchain – enabling you to understand the history of changes that have resulted in the current world state. The blockchain data structure is very different to the world state because once written, it cannot be modified. It is an immutable sequence of blocks, each of which contains a set of ordered transactions.click here to read more
We are using ledger to get the current state/data of blockchain. Without ledger we would have to traverse each block for trasaction logs & calculate current state.
Could I store my heterogeneous JSON documents in the ledger via transactions
Yes, you can store JSON documents in the ledger and create composite keys.

How to securely encrypt credit card information in a database

I have already read through Saving credit card information in MySQL database? and Storing Credit Card Information.
I'm aware that storing credit card information requires PCI compliance, which is not an easy task.
That is not what this question is about. My question is the following:
What is a secure way to encrypt user credit cards? The simplest and easiest that comes to mind is using a private key and encrypting CC's with that. This doesn't seem very secure because the key has to be stored on the server, and if an attacker can get my database, they can probably get the key too.
What I'd like to be able to do is encrypt every CC using that users password as part of the encryption process. If anyone gets the database, they can't decrypt anything because the passwords are stored as salted hashes. This would work great for transactional purchases - the user clicks "Buy," types in their password as a confirmation, I decrypt their CC and make the charge. Their password is only in memory for the duration of the request, and is never written to disk.
Unfortunately this won't work for what I'm trying to build - a service which charges a recurring fee (say, once a month), regardless of whether or not the user is logged in when I need to make the charge.
Given this scenario, is there a secure way of storing user CC's?
As you need to be able to decrypt, there's always the possibility that the encryption keys leak and you'll lose everything. So you'll never get to absolute security, but you can make it harder for attackers to get to the data.
Nobody but you can really judge what level of security (or obscurity) you should have. This is most likely a function of size of database, visibility etc.
For leaks, unfortunately you'll have to assume that everything leaks and sooner or later (e.g. with brute force attacks on weak passwords) you haven't gained too much when they get out.
Given the last credit card leak scandals - the worst ones had the 3-digit (CVV) number saved with the regular credit card number, which credit card companies explicitly forbid (that's why you'll always have to give it again even if someone has your credit card information on file)
If you don't want to assume the responsibility for holding and processing this kind of data, a good way to go is with an external payment service - let them do the processing and just assert to you that the payment has been processed. You'd have to pay them for their services, but you'd also have to pay for implementing your own solution and for taking the risk.
If you use the password as the salt for the CC encryption, it would be a very effective way of securing the information, however, they would never be able to change their password... If it is changed, then the encrypted data is lost. The bottom line for securing the encryption key is to make it as difficult as possible to find... essentially the more steps you use to hide the key, the harder it is for them to find it... which means it is harder for you to use and program for it. There is no magic bullet at this time to protect everything. (Invent a secure way to keep the key and you will be rich)
As for the CVV number, it cannot be stored as previously mentioned. With each transaction the cc processing company will give the merchant a Reference Number which is then used in each reoccurring payment. This means if the original transaction required the CVV number, then logic will dictate that the recurring payment will also be authorized by the same user who put it in on the first transaction. Therefore, the reoccurring payments will not need the CVV to maintain the same level of security.
You could essentially use multiple servers. Encrypt the cc with a key, but keep that key on a separate encryption server, the is only accessible by a master username and password for windows or whatever OS you're using. This way you're securing your key, setting up a services on the encyrption service to run the card through the encryption and then submit it to the database.
Use php's private/public openssl functions when a user makes a purchase you use the data in memory to make the purchase then you store the information using a public key to encrypt it.
To process billing monthly you decrypt the data using the private key that could be manually punched in or stored in code. If you want to store the ssl key in code and not have to remember it or get it everytime. I would encrypt the key using a salt stored in the configuration variables + buy a yubi key and generate a 32 character password + my own password on top of it. Store the yubikey in a safe place (A safe lol). When you need to process credit cards do it with a script that runs in the background and runs all billing at once. To change the password would require you decrypt all cards and re-encrypt them using the new private/public key, or you may just decrypt and re-encrypt the private key ssl.
Magic :)
You require the card information to be reversibly encrypted. The decryption information has to come from somewhere. You've said the data cannot come from the user, and you don't want it stored at the server, so it must be on separate equipment that is presumably more secure. And if you have the ability to recall that information, so does an attacker who has compromised your system. So presumably the decryption information is not retrieved at the vulnerable host during decryption.
Perhaps consider a third-party service that you can encrypt and send information to, perhaps one that specializes in PCI compliance. It might be able to decrypt the credit card information when you send it a second time and apply a charge, or it might actually store the card information for later use. It might even perform recurring transactions for you.
http://www.authorize.net/solutions/merchantsolutions/merchantservices/automatedrecurringbilling/
I just Googled that, I don't recommend them. But it's an example.
Encrypt the CC information twice. First, encrypt the credit card data based off the user's password (+ salt). Then encrypt the output of that with the server's key.
To access the information, you thus require the user's password (i.e. decrypt using server's key, then decrypt based off password). If the database and server key are compromised, the information still isn't exposed without attacking the user's password first.
It's important that the user's password is for the internal encryption - this allows you to re-encrypt when you change server encryption keys.
When the user changes their password, you also re-encrypt the data. If the user resets their password, then the CC information should be erased (and is lost anyway, as it can't be unencrypted).

Persist all users notifications in a list with redis?

I have aspects of a social network in my app and I have implemented an activity stream like this answer:
How to implement the activity stream in a social network
Like said there, every notification in the system, I push in redis for each user (key) that is notified, a list (value) of the IDs from the Activities relational table:
key value
user:1:notifications [25, 24, 23]
user:2:notifications [24, 22, 17, 13, 5, 4]
...
So, my table only has the activities and the user that causes this. What happens is that I only have the users that received the notifications in redis and nothing in mysql...
My question is that if is correct to persist this ids infinite in redis or just for a memcached of updates and periodic I trim this list?
This is more of an application architecture / design question than a programming one, so there is no one right answer in theory.
However, in practice - Redis / Memcache and many other such implementations are not meant to persist very large (or rapidly growing) data sets.
As a nosql data store, Redis uses memory, coupled with a mirror on the hard disk. So while there is no limit on the size of data you can store, ideally it should always be less than the free memory you plan to allocate to Redis.
The easiest solution to cover all bases is to store user activity data in Redis as it is generated. Use the Redis to display notifications, etc. Keep a cron running that truncates all activity logs older than a pre-defined number of days (or a pre-defined number of activities per user) and saves them to a regular database.
When a user wishes to retrieve all notifications, some speed loss is acceptable (since it is not a frequent, required or promoted action) and you can pull them from the database, by-passing Redis.
Alternative:
Again, the solution to use is best chosen based on the actual numbers of your application. But you could do this:
Store all activities in the database
For any logged in user, fetch and store all activities in Redis
On log-out remove that user's activities / notifications from Redis
When adding an activity, some additional logic required to check if the users affected are online or not. In both cases you need to add the activity to the database, but if the affected user is online, then push it to his hash in Redis as well.
You don't need to persist these notifications forever in Redis. It's quite the contrary: when user logs in, show all notifications you have for him in redis and then truncate the list (or trim it to a fixed length).

How to store data in db so that nobody with access to it can understand it?

We are soon releasing a private beta of a domestic economy website.
The website of course gathers information from a user's (identified by email only) private financial situation: salary, rent, bills, mortages, etc. All of these are really sensitive information and should not be accessible by anyone - not even us, the tech ppl.
What are best practises for storing data in a non-readable fashion? Of course, member passwords are already hashed in the db.
What I'm thinking about is to encrypt all data using some kind of key. But then again, the application needs access to that key. And I don't want to store it in the db. If supplied by user, I guess I could keep it in the session in order to decrypt every retreived db result. But what about overhead?
Pls, anyone with guidelines?
First, separate the personally-identifiable information from the statistics. This allows you to perform computations without putting sensitive data at risk. Next, strongly encrypt the personally-identifiable information, and store the keys in a hardened system with limited access. Don't use the same key for all data, but the number of keys you do use is a design decision that is up to you. More keys will be more secure, but harder to handle.
There may be existing standards that apply to your data, depending on where in the world you are and what industries you are working with. Seek these out and follow them.
Anyone with admin level access (your tech people for example) can get access to any decryption keys stored on the machine. Regarding session, any admin level person can do memory dumps to pull keys out of session.
Point is, the only "solution" of sorts is great off machine access logging combined with a strong legal document acknowledging that they are being watched and you will prosecute. Also you should perform annual background checks of your tech people. Next, the number of people with that type of access should be extremely limited. As a CEO who takes an active part in our development process, even I don't have access to our production systems.
Regardless, you should still encrypt the database, especially the PII data. Depending on your industry you could be sued if you don't, and never mind the bad press if someone does pull a data dump.
What about a second keyphrase secured by the users keyphrase? When he logs in his second will be decrypted and stored.

Secure encrypted database design

I have a web based (perl/MySQL) CRM system, and I need a section for HR to add details about disciplinary actions and salary.
All this information that we store in the database needs to be encrypted so that we developers can't see it.
I was thinking about using AES encryption, but what do I use as the key? If I use the HR Manager's password then if she forgets her password, we lose all HR information. If she changes her password, then we have to decrypt all information and re-encrypt with the new password, which seems inefficient, and dangerous, and could go horrifically wrong if there's an error half way through the process.
I had the idea that I could have an encryption key that encrypts all the information, and use the HR manager's password to encrypt the key. Then she can change her password all she likes and we'll only need to re-encrypt the key. (And without the HR Manager's password, the data is secure)
But then there's still the problem of multi-user access to the encrypted data.
I could keep a 'plaintext' copy of the key off site, and encrypt it with each new HR person's password. But then I know the master key, which doesn't seem ideal.
Has anyone tried this before, and succeeded?
GnuPG allows documents to be encrypted using multiple public keys, and decrypted using any one of the corresponding private keys. In this way, you could allow data to be encrypted using the public keys of the everyone in the HR department. Decryption could be performed by any one having one of the private keys. Decryption would require both the private key and the passphrase protecting the key to be known to the system. The private keys could be held within the system, and the passphrase solicited from the user.
The data would probably get quite bloated by GnuPG using lots of keys: it has to create a session key for the payload and then encrypt that key using each of the public keys. The encrypted keys are stored alongside the data.
The weak parts of the system are that the private keys need to be available to the system (ie. not under the control of the user), and the passphrase will have to pass through the system, and so could be compromised (ie. logged, stolen) by dodgy code. Ultimately, the raw data passes through the system too, so dodgy code could compromise that without worrying about the keys. Good code review and release control will be essential to maintain security.
You are best avoiding using MySQL's built in encryption functions: these get logged in the replication, slow, or query logs, and can be visible in the processlist - and so anyone having access to the logs and processlist have access to the data.
Why not just limit access to the database or table in general. That seems much easier. If the developer has access to query the production, there is no way to prevent them from seeing the data b/c at the end of the day, the UI has to decrypt / display the data anwyays.
In the experience I've had, the amount of work it takes to achieve the "developers cannot see production data at all" is immense and nearly imposible. At the end of the day, if the developers have to support the system, it will be difficult to achieve. If you have to debug a production problem, then it's impossible not to give some developers access to production data. The alternative is to create a large number of levels and groups of support, backups, test data, etc..
It can work, but it's not as easy as business owners may think.
Another approach is to use a single system-wide key stored in the database - perhaps with a unique id so that new keys can be added periodically. Using Counter Mode, the standard MySQL AES encryption can be used without directly exposing the cleartext to the database, and the size of the encrypted data will be exactly the same as the size of the cleartext. A sketch of the algorithm:
The application generates a unique initial counter value for the record. This might be based on some unique attribute of the record, or you could generate and store a unique value for this purpose.
The application generates a stream of counter blocks for the record based on the initial counter value. The counter stream must be the same size or up to 1 block larger than the cleartext.
The application determines which key to use. If keys are being periodically rotated, then the most recent one should be used.
The counter stream is sent to the database to be encrypted: something like
select aes_encrypt( 'counter', key ) from hrkeys where key_id = 'id';
The resulting encrypted counter value is trimmed to the length of the cleartext, and XORed with the cleartext to produce the encrypted text.
The encrypted text is stored.
Decryption is exactly the same process applied to the encrypted text.
The advantages are that the cleartext never goes any where near the database, and so the administrators cannot see the sensitive data. However, you are then left with the problem of preventing your adminstrators from accessing the encrypted counter values or the keys. The first can be achieved by using SSL connections between your application and database for the encryption operations. The second can be mitigated with access control, ensuring that the keys never appear in the database dumps, storing the keys in in-memory tables so that access control cannot be subverted by restarting the database with "skip-grants". Ultimately, the only way to eliminate this threat is to use a tamper-proof device (HSM) for performing encryption. The higher the security you require, the less likely you will be able to store the keys in the database.
See Wikipedia - Counter Mode
I am just thinking out loud.
This seems to call for a public/private key mechanism. The information would be stored encrypted with the HR public key and would only be viewable by someone in possession of the associated private key.
This, to me, seems to rule out a web based interface to view these confidential data (entering them via the web interface is certainly feasible).
Given that individuals come and go, tying the keys to a specific person's account seems infeasible. Instead, one must handle key distribution separately and have a mechanism for someone to change the keypair used (and re-encrypt the database — again without the use of a web interface) in case the current HR manager is replaced with someone else. Of course, nothing would prevent the HR manager from dumping all the data before leaving while before the keys are replaced.
I'm not sure how feasible this is currently, or what current stable DB systems have support for this, but alternate authentication mechanisms at the database level may help. For example Drizzle, a refactoring of the MySQL code base, supports (or aims to?) completely pluggable authentication, allowing no auth, server housed auth, or auth through PAM or some other mechanism, meaning you can use LDAP.
If you had different levels of access based on the database connection, and the application login also specified what you could actually access in the database, you could theoretically build a system where it wasn't possible to access the confidential database info unless using an account with specific access rights, regardless of the privilege escalation attempts in the application itself.
As long as the people setting user account access rights can be trusted or themselves are OK to see the confidential information, this should be fairly secure.
P.S. It might be useful to use a generic DB connection for "regular" application information, but when an attempt to access confidential information is made, then the specific DB connection is attempted. This allows for a few DB connections to handle most requests, assuming the majority of users aren't viewing confidential info. Otherwise, a separate DB connection per user may become burdensome to the DB.