Options for many-to-many message encryption - encryption

I have a group of (approximately) 20,000 users who need to receive encrypted messages from the public. What kind of encryption regimen should I use?
If I use PKI, I would need to share the private key with each of the 20,000 members, which is obviously a huge security risk. What other options are there?

Related

How to encrypt a message while maintaining confidentiality and integrity?

I will demonstrate my question with an example.
I want to develop a distributed application for renting cars. Since the booking details (BD) can be visible on the blockchain, I want to encrypt them and be accesible only by the intended users. Assume that the car owner and the renter have public key and private key, the car has a key (symmetric encryption) and that the onwer and the renter have agreed beforehand on the BD.
The idea is that the owner will generate an access token, from the BD, which will be published on the blockchain, retrieved by the renter and used by him to enter the car.
My question is how can I encrypt the BD in order to generate the access token while at the same time confidentiality, integrity and availability can be maintained.
One ill-solution that I have thought is that the owner encrypts the BD and their signature with the car's key (in order to generate the access token). Then he publishes the access token to the blockchain and retrieved by the renter. However, how can the renter know that the access token contains the agreed BD? Is it good practice to use a second layer of encryption such that; after the owner generates the access token he encrypts it together with the BD with the renter's public key? In this scenario, when the renter decrypts it, he has two things, an access token (which will be used to enter the car) and the booking details (verify that these are the agreed BD).
Is there a more efficient or elegant way to do this?
Thank you in advance.

Permitting Joins in SQL when encrypting data with CMEK in Google Cloud Big Query

In this video GCP engineers show how to encrypt data using a customer provided encryption key. This allows data to be encrypted E2E and the customer can keep the private key securely stored in house.
However, does this still allow joining tables based on certain values in the columns? AFAIK, encryption always adds some randomness to the message and as such, each time a value is encrypted, it will result in a different output while in its encrypted state. As such, joins should not work.
Am I correct in this belief? What are possible mitigations to enable joining despite having encryption? Any personally identifiable information is a common target for encryption, however joins, even on an encrypted value such as the customer ID, are essential for many applications.

solution recommendation to store AES encryption key of Hyperledger Fabric

Hi Hyperledger Experts:
In some cases, some organizations in a channel have the requirement to encrypt their data on the fabric network. Please refer to https://hyperledger-fabric.readthedocs.io/en/latest/chaincode4ade.html#chaincode-encryption . And the AES encryption key and decryption key are needed.
So there is a need to store some organizations' encryption key and decryption key. The fabric documentation also mentioned "If you encrypt the data then you will need to provide a means to share the decryption keys". Please refer to https://hyperledger-fabric.readthedocs.io/en/latest/Fabric-FAQ.html
So the question is: what is the advisable way to store the AES encryption/decryption keys? Where to store them?
Apart from fabric network, do we need a separate centralized database to store them? Or can we directly store them on fabric network, and only let specified organizations to get them? Thanks very much!
I'm not an expert in data security but I believe your problem can be solved using Private Data present in hyperledger fabric framework itself.
It is confidential data that is stored in a private database on each authorized peer, logically separate from the channel ledger data. Access to this data is restricted to one or more organizations on a channel via a private data collection definition. Unauthorized organizations will have a hash of the private data on the channel ledger as evidence of the transaction data.
Refer to docs to understand how to use this to store your AES keys.

Yii2 Encryption generates different encryption data

I am using encryptByKey() for SSN and Account Number encryption in Yii2. The problem is that it generates different encrypted data for the same Account Number when I try to re-generate it.
I can't match it in the database like the following:
Customers::findOne(['account_number'=> Yii::$app->getSecurity()->encryptByKey($account_number, "someKeyHere")]);
Is there any encryption method available to generate same encrypted data every time I encrypt it?
Thanks,
Generally, that's the way encryption is supposed to work. It is sometimes called "ciphertext indistinguishability." Yielding the same ciphertext every time a given plaintext is encrypted undermines security by allowing attackers to analyze collections of ciphertext for patterns.
In this case, it looks like you only store one instance of the encrypted account number; you could argue that because the "message" is never repeated, cipher text indistinguishability is moot. That could lead you to justify the use of ECB mode (if your API offered it) or a HMAC (message authentication code, offered by the hashData() method) to compute a lookup key. If an attacker gets access to your database, there will only be one instance of each key, and nothing is revealed.
However, this is still insecure if an attacker can provide account numbers that your system encrypts. For example, an attacker could pose a legitimate user and provide a SSN during registration. If they choose a duplicate number, and then look in the database, their maliciously chosen encrypted value will match a legitimate record. Or, if the system rejects their account number because it is a duplicate, the attacker will know that it is a number in use by a legitimate user. This is called an oracle attack.
If you use an HMAC (or ECB mode encryption), you would have to design your application very carefully to prevent chosen plaintext and oracle attacks. And, candidly, if you are now encountering these ideas for the first time, there are probably many other gaps in your knowledge that will lead to easily exploited vulnerabilities in your application.

storing credit card info

So I would like to modify a PHP / MySQL application in order to store credit card but not cvv and bank account info securely. PCI DSS require 1024 RSA/DSA. A small number of users will be given private key in order to decrypt the batch file of account info for submission to payment processors monthly. I'm unclear if it is possible to have a system that would allow the users who have signed in with normal 8 digit passwords to modify their own account info securely. It seems that this is not possible, and the encryption should be one-way (ie each user -> admins; never allowing user to decrypt their own info again), with account info never exposed back to users even over SSL connections. Or is there a proper and easy way to do this that I'm unaware of that is PCI DSS compliant?
PCI DSS does not require 1024 bit RSA to encrypt. Older versions of the specification mentioned AES and 3DES by name, but I believe newer versions just specify strong encryption. Most people are using AES 256.
Encrypting data at-rest with an asymmetric algorithm doesn't really work. Symmetric algorithms work best. This allows the application to access the card data when it needs to. This doesn't mean you have to show the data to the user ever again, it just means the data is there when you need to get to it. If you're storing credit card authorization information, you'll usually need the card number for settlement. (It really depends on the features your processor has. Some of the small-business level processors store the card for you, but this is infeasible for large scale processors like Paymentech and FDMS.)
The problem is that you will have to rotate your encryption keys periodically. This is usually what screws everyone up. If you roll your own encryption, you need to make sure that you can specify n number of keys that are accessible for as long as there is data encrypted with those keys. At any point in time, only one of those keys should be used for encryption. Unless you have a deep understanding of crypto and key management in terms of PCI, you might want to go with a commercial offering. Yes, these are expensive, but you have to determine the best course with a build or buy decision making process.
Ingrian (now SafeNet) has a decent offering for a network HSM. It will manage the keys for you and do the cryptographic operations. It may also be possible to use their DB level encryption integration so that you don't have to change your application at all. (Though DB level encryption is dubiously secure in my opinion.)
This is a very deep subject; I've done a lot with PCI and suggest you hire someone to guide you through doing it properly. You'll spend a lot of money on false starts and redoing work, so get an auditor involved early to at least asses what you need and tell you how to implement the security properly.
You may have an easier time if you differentiate between data storage, access, and transmission.
Storage requires strong reversible encryption; the data is not useful unless you can retrieve it.
Access requires a user or process to authenticate itself before it is permitted to decrypt the data. Here's an example of a mechanism that would accomplish this:
Store the data with a secret key that is never directly exposed to any user. Of course, you'll need to store that key somewhere, and you must be able to retrieve it.
When each user chooses a password, use the password to encrypt a personal copy of the private key for that user. (Note: even though you're encrypting each copy of the key, security issues may arise from maintaining multiple copies of the same information.)
Do not store the user's password. Instead, hash it according to standard best practices (with salt, etc.) and store the hash.
When a user provides a password to log in, hash it and compare to your stored value. If they match, use the (plainitext) password to decrypt the key, which is then used to decrypt the actual data.
Transmit the data through a secure connection, such as SSL. It's reasonable (perhaps required) to allow users to access (and modify) their own data, as long as you continue to follow best practices.
Comments:
An 8-digit password implies a key space of 108 ~ 227 = 27 bits, which by today's standards is fairly terrible. If you can't encourage longer (or alphanumeric) passwords, you may want to consider additional layers.
One advantage to the multiple-layer strategy (user provides a password that is used to encrypt the "actual" key) is that you can change the encryption key transparently to the user, thereby satisfying any key-rotation requirements..
The standard admonition whenever you're designing a security solution is to remember that DIY security, even when following standards, is risky at best. You're almost always better off using an off-the-shelf package by a reputable vendor, or at least having a trained, certified security professional audit both your strategy and your implementation.
Good luck!

Resources