Search code examples
securityencryptionprivate-key

Can we encrypt data that must be decrypted with any private key plus a server generate bits?


I have come up with a scenario to make a secure data. Suppose I have a public encrypted file that anybody can download. But whenever anyone want to decrypt that data they need to get a key from server

To make the key cannot be shared. The key from server will not be able to decrypt the data directly. But the data must be decrypted with the client's private key after, without server knowing those client's privateKey

I hope below diagram could explain it clearly

enter image description here

Is it possible? What is the algorithm that could do this?


Solution

  • I have come up with a scenario to make a secure data. Suppose I have a public encrypted file that anybody can download. But whenever anyone want to decrypt that data they need to get a key from server

    To make the key cannot be shared. The key from server will not be able to decrypt the data directly. But the data must be decrypted with the client's private key after, without server knowing those client's privateKey

    Make it so each time the file is downloaded, a random string is appended. The file is then encrypted with the user's public key, and symmetrically with an appropriate hash generated by that same string. For example a GPG file inside a password-protected ZIP file.

    So Alice downloads Financial_Report_201809_d8a1b2e6.pdf.zip while Bob downloads Financial_Report_201809_ff2a91c3.pdf.zip.

    If they want to decrypt the file, they need to send the server back the random string, and the server will supply them with the password for the outer ZIP. Then they're left with an encrypted file that only their private key can decode.

    Note that once they have decrypted the file, nothing stops them from forwarding the file in the clear to someone else. On the other hand, sharing the encrypted PDF avails them nothing, as they would also need to share their private key.

    Also note that since they need to be online to get the outer password, and they're left with a cleartext file at the end, this is (almost) functionally equivalent to the file being downloaded in the clear once user identity has been established.

    The main differences are:

    • the ciphered file (PDF in the above example) might not have been encrypted by the server at all. It might have been supplied by the user, who is then satisfied that only he can read the file back (it makes little sense for anyone else to download it, though).
    • the transmitted file is very securely transmitted. An attacker with full access to the datastream would not be able to decode the file (but this is no more than could be gained by just encrypting with the user's public key - no extra ZIP stage required).

    UPDATE

    You want to encrypt the whole file only once (for all users), and then send the same file to Alice and Bob, and have them require two different keys at decryption time. The problem here is that Alice's key will also work on Bob's file, since it is the same file. There's no magic that's going to work here, unless you can hide some detail of the decryption process (e.g. use a program that you control and that can't be debugged and that will always connect to your server: a proposition that has consistently shown to be losing).

    If you want to limit the encryption cost, you can send the massive file with both a symmetrically encrypted data payload (always the same) and a very short, asymmetrically encrypted key payload (always different), but still you will be vulnerable to the decrypted key being captured:

    [ RSA(ALICE.PUB, "SQUEAMISH OSSIFRAGE" ][ RIJNDAEL("SQUEAMISH OSSIFRAGE", LARGE FILE) ]
    

    In the above scenario some program has to read the encryption header and decrypt the 'Squeamish Ossifrage' password, then go on decrypting (e.g. playing) the extra payload without the password being intercepted. This means that you need to supply the program yourself.

    This is functionally equivalent to the program connecting to the server and downloading a "yes" or "no" to the question (appropriately encrypted, signed and secured) "I am Alice's player. Can I decrypt and play 'Never Wanna Give You Up.avi'?" , with no passwords or public keys being known or exchanged apart from the secret shared by Alice's player and the server.

    UPDATE II

    If the goal is to save encryption resources, the encryption could be made client side as hinted in the comment:

    • the file is encrypted the once, with a purpose-generated private key.
    • the private key is stored inside a binary (we must assume it to be unhackable).
    • the user has to supply his public key for the decryption to work
    • the program can verify the public key from a repository (or, alternately, the user can supply the public key to the server, which will generate and send the binary file for download)
    • the program then runs both the decryption and reencryption
    • the user is left with a file encrypted with his public key, that he alone can decrypt.

    UPDATE III

    In order for the cleartext file to never be exposed (i.e., it does not matter whether the algorithm gets leaked), you could devise the following scheme. Keep in mind that I'm not a cryptographer and there could be all sort of side channels left uncovered.

    • You prepare a conversion table that maps each 16-bit word into another 16-bit word. This is a flavour of symmetrical encryption, even if you use two reciprocal matrices for encoding and decoding. Each matrix holds all possible 16-bit words, which means 65536 values, and is therefore 128 Kb in size.
    • You encrypt the file, once, with the encryption matrix. Without the decryption matrix, the file is unusable.
    • The user has to send you his public key.
    • You prepare a transmogrification matrix by encrypting each word with that key, and use the decryption value as an index.

    So, for example, say the first word of the cleartext file is A18B. In the encryption matrix, after the scramble, the A18B-th position will contain say 701C, and the decryption matrix, therefore, in the 701Cth position, will hold a18b.

    The user has a file starting with 701c... which is of no use.

    The user sends you his public key and you run 65536 encryptions on all words from 0000 to ffff. You then determine that the encryption of a18b is 791c. You prepare a re-encoding matrix that has 791c in the 701cth position.

    You then send the user this matrix, which has 128K bytes, where the 701cth position is 791c.

    The user runs the transmogrification, which is very fast, and is left with a file starting with 791c (as the 701c became 791c - I mistakenly chose two similar values in my example, that is of no significance). This value, once decrypted with his private key, will yield a18b which is the "readable" value.

    The user has now a file that's been encrypted by his public key. The a18b value never appeared anywhere.

    All that's left is for the user to decrypt the file using his private key and a code block size of 16 bits. This operation will be run by the client and be quite slow, and it's the reason why usually a large random quick symmetric key is RSA-encoded, and used to symmetrically quickly encrypt the large file, which can be quickly decrypted after the private key has unlocked the symmetric key.

    The user cannot send the 128K to anyone, for they're useless without the private key.

    (The problem here is still that the user can now decrypt the file with his private key, and send it around, even if it's unwieldy as it's a very large file).