Our product stores voucher data in a database. These voucher data can be retrieved with our app to display a voucher that can be used for payments.

Obviously, these voucher data are extremely sensitive because who ever gets access to them can use them for payments. Common attack scenarios are:

  • DB breach where an attacker can extract voucher data from our database
  • Man-in-the middle where an attacker spies on the communication between our backend and our app
  • Internal staff with database access extracts voucher data with malicious intention

To reduce risk we decided that we need to encrypt these voucher data. The goal is, that only the app user who owns the voucher can decrypt it. The backend must not under any circumstances store keys that can be used for decrypting voucher data.

We figured that asymmetric crypto should be a good fit for our requirements. The solution would look something like this:

  1. The app generates an asymmetric key pair locally and stores the private key locally while the public key is uploaded to our backend
  2. The backend uses the user's public key to encrypt the voucher data and store it in the DB
  3. The encrypted voucher data is sent to the app when a user wants to retrieve his vouchers
  4. The encrypted voucher data is decrypted locally with the user's private key

The only thing we're still looking for is a good asymmetric algorithm. RSA seems pretty fine, but only huge key lengths like 4096 upward are considered secure nowadays. The limit what key lengths are considered secure also increases continuously as the years go by. Since our concept also involves a master key stored on a hardware token, this will not do because most hardware tokens only support RSA key sizes up to 2048 bits.

ECC on the other hand seems pretty secure with much shorter key sizes and has good hardware support. Blockers are that ECC is mostly used for signing stuff and we couldn't find a way to use it for encryption/decryption.

Are there any other options that combine good security with good hardware token support?


2 Answers 2


ECC is mostly used for signing stuff and we couldn't find a way to use it for encryption/decryption.

It is possible to use ECC with an integrated encryption scheme (IES), where a single-use symmetric key is generated using a secret based on a public key, in such a way that only the holder of the private key can re-derive the secret and thus the symmetric key. The message is then encrypted using the symmetric key, which is subsequently discarded; the only data stored/transmitted are the ciphertext (with metadata such as IV/nonce and integrity tag) and a value computed using the recipient's public key. This is a hybrid cryptosystem rather than directly encrypting using asymmetric crypto, and requires agreement on the IES parameters, but it's secure, works on arbitrary-size messages, and is tolerably performant (certainly better than RSA with very large keys). I don't know how widespread support for it is, though, especially in hardware tokens.

I'm skeptical that your users will accept this scheme, though. Needing to carry a hardware token rather than just remember a password is a big step up, and while it's one that security experts have been pushing for years (security tokens can protect against attacks not even the best password is proof against), adoption has been terrible. Meanwhile, tons of companies store literal payment information - credit/debit cards or bank account+routing numbers, to say nothing of things like digital (or physical) gift cards, coupon codes, and loyalty points - not to mention the actual prices that will be charged - and don't generally have a problem with people stealing the DB full of payment-ready info and running off to get rich with it.

Given all that, this feels like massively overcomplicating things. Let's suppose, against all likelihood, that the value of these vouchers is one million USD, a life-changing amount for most people and sorely tempting even for those with cushy software engineering jobs, but scarcely worth nation-state interest. It's also easily enough to be worth taking some basic precautions with, like creating an audit log of when each voucher is created and who it's created for and in what amount and with what expiration and so on. Any attempt to redeem the voucher should obviously consult the log to ensure the voucher and amount is valid, and log the attempt (succeed or fail) so that the voucher can't be used again or anything like that (beware the time-of-check/time-of-use race condition). Permission to create or read log entries should be tightly limited to the services that need it, and permission to edit or remove them shouldn't exist at all.

Now, you might be objecting "hey, that's not as secure as end-to-end asymmetric encryption with hardware-resident private keys!" but in practice, it really is. An attacker who can edit the log directly can almost certainly also carry out other attacks, such as modifying a legitimate user's public key such that the voucher is encrypted to the attacker's public key instead (and hence decryptable by the attacker), or modifying the system to generate a voucher for the attacker even though they aren't eligible, or modifying the system to make it always give the attacker the voucher's deal, or modifying the system to pass on every token generated to the attacker too, or extracting the voucher-generating code and running it directly, or several other equivalent attacks. You need either to actually prevent insider threats, or to accept the risk.

The security measures to prevent these attacks are all the same, and in common use in software enterprises: mandatory code reviews before merge, restricted access to the production environment, no ability to deploy code directly, pervasive monitoring/logging/alerting of suspicious activity, etc. Combine with measures that are truly standard operating procedure, such as using TLS (to prevent man-in-the-middle attacks) and encryption at rest (to prevent attackers from stealing DB drives or backup tapes and reading secrets out of them), and you've prevented all the attacks you were worried about, and more besides (which your proposed solution wouldn't have addressed, at least not alone).


The only thing we're still looking for is a good asymmetric algorithm. RSA seems pretty fine, but only huge key lengths like 4096 upward are considered secure nowadays.

Secure against what?

The vouchers should be designed to be worthless when used. Thus probably rather shortlived. NIST writes this:

The security strength is measured in bits and is, basically, a measure of the difficulty of discovering the key. The understood security strength for each algorithm is listed in SP 800-57. For example, RSA using a key length of 1024 bits (i.e., 1024-bit RSA) has a security strength of 80 bits, as does 2-key Triple DES, while 2048-bit RSA and 3-key Triple DES have a security strength of 112 bits. See Table 2 in Part 1 of SP 800-57 for further security strength information.

This may be a problem in a context where you need the data to remain secure for ten years. You probably don't need that; you need to keep it secure for a much shorter time frame, and what more: you can rotate it if you want - let each voucher be valid for say 1 month, then generate a new one, encrypt and place in database, so that the window of attack is arbitrarily short.

You don't need perfect secrecy; you only need to make it more expensive to crack vouchers than to pay with cash. And I can't see why RSA-2048 is not enough - especially if you rotate secrets periodically.

That said - I can't see why the vouchers are more sensitive than other DB elements; can't fake orders with "Yup, all paid"-status be injected in to the database?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .