I am building an app that uses Intel SGX to sign a certain type of activities the app performs. Within a Secure Enclave I generate a statement X of the kind "operation A was performed with result B". Next, I generate a one-time key Y to sign this statement. The key X itself is a part of an SGX quote, i.e., is signed with the chain of keys (K1, K2, ...) provided by SGX technology. This chain terminates at the so called Intel SGX Root Key (R).
R -> K1 -> K2 -> ... -> Y -> X ("operation = A ; result = B")
I want to store statement X somewhere else such that 1 year later anyone would be able to verfiy that indeed an operation A was performed with result B. In this case, the verifier would unwind the chain of trust starting from the Intel SGX Root Key (R) until they reach my one-time key Y, and finally verify the statement X.
The question is, where do I get the key R from?
When we deal with this type of cryptographic schemes, the ultimate key to trust is somewhere in the public, e.g., on one of the main pages of Intel's website. However, it is kind of challenging to find it. Any idea where one could obtain it from?
Related
I would like to use an asymmetric encryption process without making the "public" key really public.
My world contains 3 actors : A, B, C and a public message bank.
I want A to be the only one able to encrypt (and decrypt) short messages in the bank (for example AES keys), and I want A to be able to later chose who gains access to the encrypted data in the bank without the need to re-encrypt or add messages to the bank.
It would go like this:
A generates a key pair with RSA : (p1,p2), p1 being the "private" key (used here only for encryption) and p2 being the "public" key (used here only for decryption)
A encrypts the messages with p1 and stores them in the public bank : A, B and C can access the stored encrypted messages. For now, only A can decrypt the messages.
Later, A wants B (and only B) to be able to read the messages (but not to write more messages in his name in the bank), so he gives p2 to B in some secure way.
Is it a correct use of the RSA algorithm ? Does RSA ensure that B and C will not be able to read M without the "public" key p2?
Why does the vocabulary around asymmetric encryption seem to deter me from doing so? Is there a better way to achieve the same functionality ?
Any advice would be much appreciated
EDIT :
I know that I'm not using the RSA protocol in the usual way (public key encryption/ private key decryption), but the math behind it (as I understand it) should allow working the other way around.
I'm writing an application which I want to be able to supply RSA encrypted tokens to clients via a web API.
I'm using the crypto-pubkey library for RSA, for example:
encrypt :: CPRG g
=> g -- ^ random number generator.
-> OAEPParams -- ^ OAEP params to use for encryption.
-> PublicKey -- ^ Public key.
-> ByteString -- ^ Message to encrypt
-> (Either Error ByteString, g)
In my case, the message is the AES content key used to encrypt the token. I can create a CPRG instance using the cprng-aes library which provides an AES counter mode implementation:
makeSystem :: IO AESRNG
which is the same implementation that Yesod uses in its ClientSession module. I've taken a look at that and it stores a global instance behind an IORef and uses it to implement a function for generating initialization vectors inside an atomicModifyIORef call.
This is OK since the function just pulls some bytes out of the generator and returns them, writing the new CPRG instance back to the IORef. However the RSA API needs to be passed a CPRG instance directly, and even if I could carry out my token generation within a call to atomicModifyIORef, it's likely to be a much more costly operation and lead to contention issues.
One idea I had was to pull out adequate data from a global instance in advance before calling the encryption API, and wrap it up in a CPRG instance backed by a ByteString, but that's a bit of a fragile hack, as it requires prior knowledge of the internals of the token generation process -- the content key size, RSA padding and so on, which may vary depending on the parameters chosen.
What are the best options for managing the random number generators required by pure functions like the above RSA API when they are used in multi-threaded client-server applications?
I would recommend using a pool of CPRG instances, if the numbers say you need this. It's probably worth doing some basic profiling first to see if the simple atomicModifyIORef approach would be a bottleneck.
For pools, you can use http://hackage.haskell.org/package/resource-pool, or http://hackage.haskell.org/package/pool-conduit (which is based on resource-pool).
I am having hands on trying to make a hack-proof website and learning about XSS. So the process is
A: Get User Input -> B: Store It -> C: Show It Again To client
I am using Microsoft AntiXSS library to avoid XSS attacks, but, the confusion is, should I perform required steps to avoid XSS attacks at step 'B' or at Step 'C'.
You should perform the sanitisation at the point where you are presenting the content, because this is the only point where it matters.
In a more complicated scenario, your data-flow may look like this:
/---> C (presentation)
A (get input) -> B (store)
\---> D (process)
If you've already sanitised the data at point B, then the processing at point D won't be able to operate on the original data.
I need to generate random tokens so that when I see them later I can determine absolutely that they were actually generated by me, i.e. it should be near impossible for anyone else to generate fake tokens. It's kind of like serial number generation except I don't need uniqueness. Actually, its a lot like a digital signature except I am the only one that needs to verify the "signature".
My solution is as follows:
have a secret string S (this is the only data not in the open)
for each token, generate a random string K
token = K + MD5(K + S)
to validate the token is one I generated:
split incoming token into K + H
calculate MD5(K + S), ensure equal to H
It seems to me that it should be impossible for anybody to reliably generate H, given K without S. Is this solution too simplistic?
Check out HMAC.
The solution you presented is on the right track. You're essentially performing challenge-response authentication with yourself. Each token can consist of a non-secret challenge string C, and HMAC(C, K) where K is your server's secret key.
To verify a token, simply recompute the HMAC with the supplied value of C and see if it matches the supplied HMAC value.
Also, as Vinko mentioned, you should not use MD5; SHA-256 is a good choice.
That's not too simplistic, that's certainly a valid way to implement a simple digital signature.
Of course, you can't prove to anybody else that you generated the signature without revealing your secret key S, but for that purpose you would want to use a more sophisticated protocol like PKI.
Just to nitpick a bit you would prove only that whomever has access to S could have generated the token. Another little detail: use a better hash, like SHA256. Because if Mallory is able to generate a collision, she doesn't even need to know S.
What are the fundamentals to accomplish data encryption with exactly two keys (which could be password-based), but needing only one (either one) of the two keys to decrypt the data?
For example, data is encrypted with a user's password and his company's password, and then he or his company can decrypt the data. Neither of them know the other password. Only one copy of the encrypted data is stored.
I don't mean public/private key. Probably via symmetric key cryptography and maybe it involves something like XORing the keys together to use them for encrypting.
Update: I would also like to find a solution that does not involve storing the keys at all.
The way this is customarily done is to generate a single symmetric key to encrypt the data. Then you encrypt the symmetric key with each recipient's key or password to that they can decrypt it on their own. S/MIME (actually the Cryptographic Message Syntax on which S/MIME is based) uses this technique.
This way, you only have to store one copy of the encrypted message, but multiple copies of its key.
Generally speaking, what you do is encrypt the data with a randomly generated key, and then append versions of that random key that have been encrypted with every known key. So anybody with a valid key can discover the 'real' key that was used to encrypt the data.
If I understood you correctly, you have some data that you are willing to encrypt and distribute the encryption key splitted into n 'key pieces'.(In your case 2 pieces)
For that you could use the XOR based splitting, here is how it works:
You provide the required number of pieces - n, and the secret key – K. To generate n pieces of your key, you need to create (n – 1) random numbers: R1, R2, R3, . . . , Rn−1. For that you can use a SecureRandom number generator, which will prevent us from duplicates.Then you operate XOR function on these Rn-1 pieces and your key - K:
Rn = R1 ⊕ R2 ⊕ R3 ⊕ . . . ⊕ Rn−1 ⊕ K
Now you have your n pieces: R1, R2, R3, …, Rn-1, Rn and you may destroy the K. Those pieces can be spread in your code or sent to users.
To reassemble the key, we use XOR operation on our Rn pieces:
K = R1 ⊕ R2 ⊕ R3 ⊕ . . . ⊕ Rn−1 ⊕ Rn
With the XOR function (⊕) each piece is inherently important in the reconstruction of the key, if any bits in any of the pieces are changed, then the key is not recoverable.
For more info and code, you can take a look at the Android Utility I wrote for that purpose:
GitHub Project: https://github.com/aivarsda/Secret-Key-Split-Util
Also you can try the Secret Key Splitter demo app which uses that Utility :
GooglePlay: https://play.google.com/store/apps/details?id=com.aivarsda.keysplitter
I think I thought of a solution that would work:
D = data to encrypt
h1 = hash(userpassword)
h2 = hash(companyPassword)
k = h1 concat h2
E = function to encrypt
//C is the encrypted data
C = E_h1(h2) concat E_h2(h1) concat E_k(D)
Then either person can decrypt the hash of the other person, and then combine them to decrypt the rest of the data.
Perhaps there is a better solution than this though?
In the more general case, a secret (in this application, a decryption key for the data) can be split into shares such that some threshold number of these shares is required to recover the secret. This is known as secret sharing or with n shares and a threshold of t, a (t,n)-threshold scheme.
One way this can be done is by creating a polynomial of order t-1, setting the secret as the first coefficient, and choosing the rest of the coefficients at random. Then, n random points on this curve are selected and become the shares.