Can CryptoKey objects be stolen during an XSS attack? - jwt

Crypto keys stored in IndexedDB with {extractable: false} cannot be exported. In other words:
the key itself cannot be retrieved
but the CryptoKey object that owns the key has APIs that can be used to encrypt, decrypt, verify, or sign data based on that key.
Now, is it possible that a malicious XSS script could access IndexedDB and steal the CryptoKey object itself (not steal the key alone, but steal the entire CryptoKey object that owns the key) and use it to encrypt, decrypt, sign, or verify data?

Related

Is KMS data key pairs secure?

So, I'm building an application for MTLS authentication and generate X509 certificates using AWS ACM PCA and bundle them together with a private key in PKCS#12 format.
At the moment I generate key pairs programatically in Java which are never stored.
But since I'm not a security expert I thought maybe it's better to use AWS KMS for creating key pairs.
So, it seem like what I need is a CMK which can generate data key pairs which are stored in KMS.
If they're stored in KMS and I can fetch the private key at any time, how is that more secure than not storing it at all?
Or is the purpose of KMS only to store keys securely?
If you have a use for the encrypted private key that kms.generateDataKeyPair will provide, then it would be of use. It would also be a nice way to ensure that your keys are being generated securely (secure randomness, etc).
It’s important to note, KMS will not store the generated key pair. The idea is that you would store the plaintext public key, and the encrypted private key, and call kms.decrypt to turn the encrypted private key into plaintext whenever you need it.

Storing keys - Should I store private keys in PEM or JWK JSON format?

Which is more conventional?
For cross-platform; it is ok to store and use JWK in the JSON format?
Do I need to encrypt them before storing it in a database?
Not sure about the format, but I'd strongly recommend against storing private keys as much as you can. These are considered secret.
However, it seems like JWK is about the public keys (as opposed to the private keys) - and these are okay to store. I'd just make sure they can't be replaced by anyone without proper permissions
Should I store private keys in PEM or JWK JSON format?
The main reason for choosing one format or the other mainly depends on the application/library needs.
In general, you want to avoid unnecessary conversion on runtime and serve directly on the required format.
For cross-platform; it is ok to store and use JWK in the JSON format?
Can you elaborate more on this use case?
Do I need to encrypt them before storing it in a database?
Not necessarily. As you tagged this question with [jwe], I understand that the private key is used to decrypt the token you receive.
If this is is stored on a backend server, the risk of key leak is low and if you encrypt it you will undoubtedly need to store the decryption key somewhere that you should also store securely. This has no benefit and you will be required to decrypt it each time you want to use it and thus use CPU time for nothing.
Note that storing private keys in a database is not recommended. It should be stored as a file on the server or set as an env var.
If the private key is stored on a roaming device (smartphone, PC...), it is highly recommended to encrypt it has those devices are considered less secured because of physical attacks. They usually provide convenient ways to encrypt such keys (Android keystore, IOS Keychain, Windows keystore and certificate...).

Hybrid content encryption for multiple authorized users (FE and BE)

At the moment I want to implement a method that stores certain data server-side only encrypted. For this procedure is provided that each authorized user receives a private key, with which he can store and read encrypted data. Now it is so that several authorized persons are allowed to look at the same encrypted content. This means that if person A stores data encrypted with his private key, person B (if authorized) can also read this data with his private key.
The idea of ​​implementation:
For all authorized persons, a single symmetric key is generated on the server side. The key is used to encrypt and decrypt plain text data. Now, for each individual claimant, a key pair is generated (public and private). With the public key, the symmetric key is encrypted and stored for the user and there are several of these asymmetrically encrypted symmetric keys on the server. The private key is given to the user (as a file download, HTTPS), which later can be used to decrypt the encrypted symmetric key. Therefore He can upload his private key before writing or reading encrypted data, in a web application (client side) and send it to the server. The Server uses the private Key to encrypt the content of the user and save it, or decrypt older content and send it in plain text to the user.
My problem now is that the weak point is the server, where the private key of the user must first be sent to encrypt and decrypt. There might be someone with access this private key secretly intercept and save.
My question now: Is there an alternative to the approach or does one have to do so if he wants to implement such a procedure? It is important that the data is stored only encrypted. And also this must be implemented with a client web-application and a backend.

What sort of algorithms are involved when an application deciphers the token by the issuer in SSO?

In case of claim based authentication which uses SSO, an application receives a token from the issuer for a particular user and that token contains the claims as well as some sort of digital signature in order to be traced by the application that an issuer is a trusted one.
I want to know, if there are some sort of algorithms involved by which this application recognizes an issuer?
I had read that issuer has a public key and all the other applications have their own private key, is it true?
There are many protocols, formats and methods of doing Single Sign On such as Security Assertion Markup Language (SAML), OpenID and OAuth. The goal is for one entity, such as a website, to identity and authenticate the user (such as through a user name and password) and other entities, such as other websties, trust the evidence of that authentication through a token. This means users need not remember yet another password and each website maintain their own list of passwords.
This trust is usually enforced through cryptography using a digital signature. Digital signatures are used because it allows the trusting entity to verify token was (1) issued by the authenticating entity only and (2) not tampered with without being able to impersonate (pretend to be) the authenticating entity.
As you say above, this is performed using asymmetric or public key cryptography. Symmetric cryptography, such as the AES or DES algorithms, use a single key to encrypt and decrypt data. Asymmetric cryptography, such as the RSA algorithm, uses two related keys. Data encrypted using one can only be decrypted by the other and vice versa.
One key is usually kept secret, called the private key, and the other is distributed widely, called the public key. In the example above, the authenticating entity has the private key that allows it to encrypt data that anyone with the public key can decrypt.
It would seem to follow that the authenticating entity would just encrypt the user details and use that as the token. However, commonly used asymmetric algorithms like RSA are very slow and encrypting even small amounts of data can take too long.
Therefore, instead of encrypting the user details, the authenticating entity generates a "hash" or "digest" and encrypts that. A hash algorithm converts a piece of data into a small number (the hash) in a very difficult to reverse way. Difference pieces of data also create different hashes. Common hash algorithms include Message Digest 5 (MD5) and Secure Hash Algorithm (SHA) and its derivatives like SHA1, SHA256 and SHA512.
The hash encrypted with the authenticating entity's private key is called a digital signature. When it receives the token, the trusting entity decrypts the token using the authenticating entity's public key and compares it to a hash it calculates itself. If the hashes are the same, the trusting entity knows it has not been modified (because the hashes match) and it must have come from the authenticating entity (because only it knows its private key).
If you want more information about SAML and claims-based authentication, I found this video very helpful. It does get complicated rather quickly and you may need to watch it multiple times but Vittorio covers most of these concepts in great detail.

Symmetric key transfer Vs asymmetric for encryption and signing on mobile device

Scenario
A SOAP web service provides an interface for retrieving documents and data. Security is paramount.
WS-Security is used and both the client and server encrypt and sign the entire SOAP envelope.
Questions
Should the private key used for signing be compiled into the application and stored on the device or should it provided by the server using a key exchange protocol (perhaps after authentication of the user)?
Should the private key for decryption be stored on the device or provided by the server?
Is it realistic to have a unique key for each file that is to be decrypted by the server (if uploading from client) or decrypted by the client (if downloading from server)?
Just a couple suggestions:
-You should consider symmetric keys embedded into anything outside your server as public due to reverse engineering (i.e. don't bother even encrypting if the key is out in the wild).
-You should use a per-session symmetric key generated by a secure RNG on the client, and transmitted to the server encrypted with the global asymmetric public key. Private keys have a shelf-life.
-You can use the session key for all files/streams transferred in that session, but you should use a unique nonce to salt the symmetric-key encryption for each file. Depending on the encryption mode, using the same key/nonce with more than one stream can leave you vulnerable to XOR'ing the two streams and recovering a mashed-together but unencrypted result.
The entire concept of a private key is defeated if it has to be transmitted from one device to another. Each end of the communication channel must generate their own private keys. Note, that this doesn't mean compiling private keys into an executable, because then everyone with the executable shares a private key, which is obviously not what you want. Each individual device has to use a cryptographically secure source of random numbers to generate it's own public/private key pair. Then public keys can be exchanged in the clear, you can use them to exchange session keys (which can be unique for each and every file), private keys can sign, and everybody is happy.
But remember: Never, ever hard code private keys, and never, ever share them with anybody.