Is KMS data key pairs secure? - amazon-kms

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.

Related

How can I import a local asymmetric private key to AWS KMS and use?

I'm going to import my local asymmetric private key into KMS and use it in the VPC only.
It seems importing an asymmetric key is not support in AWS KMS.
https://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html
It is not supported on asymmetric KMS keys, HMAC KMS keys, or KMS keys in custom key stores.
But this seems available by using AWS cloud HSM
https://docs.aws.amazon.com/cloudhsm/latest/userguide/key_mgmt_util-importPrivateKey.html
The importPrivateKey command in key_mgmt_util imports an asymmetric private key into an HSM.
So, My question is, How can I use this imported key in KMS?
I found this https://docs.aws.amazon.com/kms/latest/developerguide/create-cmk-keystore.html
You cannot create asymmetric KMS keys, HMAC KMS keys or KMS keys with imported key material in a custom key store.
then, I guess, I can upload a private key to cloud HSM, but it won't be able to use in KMS. right? I'm so confused with those articles. isn't there a way to use an asymmetric key of cloud HSM in KMS?

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...).

Getting the KMS key from KMS CipherTextBlob

How do I get the KMS key information from the ciphertext blob?
Taking the example from the aws website
AWS KMS doc
aws kms encrypt --key-id 1234abcd-12ab-34cd-56ef-1234567890ab --plaintext fileb://ExamplePlaintextFile --output text --query CiphertextBlob | base64 --decode > ExampleEncryptedFile
Is there any way to look at ExampleEncryptedFile and figure out which KMS key was used to encrypt it?
I ask because I'm having a problem reading something I encrypted and I want to verify it was encrypted with the key I thought it was.
Yes, you can get the key id by using aws kms decrypt (pass it the ciphertext and region) which does not require a key id to perform decryption. The information about the key that was used to encrypt is part of the ciphertext, therefore, KMS will be able to get this information and return you the "Plaintext" and the "KeyId".
I'm afraid you won't be able to do it. The encrypt API uses a customer master key (CMK) to encrypt the data, and that key never leaves AWS. Unless you saved the key ID somewhere (which is not a great practice), you won't be able to derive it from the encrypted file.
A couple things that can help, in case you have administrative access to the AWS console:
literally try calling aws kms decrypt using the master keys you have (assuming they are not many and the original one has not been deleted);
looking at your CloudTrail logs, you might be able to figure out which key was used if you have a rough idea of the time when it was used (assuming you have CloudTrail enabled on your KMS operations).
The encrypted blob contains the key information required to decrypt it. There is no way to figure out what key an encrypted blob was encrypted with as its part of the encrypted value.
If you’re you’re unsure which key you used, you will have to either roll the value and encrypt it again or start attempting to decrypt with permissions that only have access to one key at a time..

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.

public/private key authentication and signing

I'm working on a Single Sign On solution to allow my company to integrate with other vendors.
As I'm doing my research, one thing is constantly confusing me.
My understanding of Public/Private key is that data is always encrypted with the vendor's public key and they decrypt using their private key. So far so good.
However, to validate that the message is really coming from me, I will compute the hash of the message and encrypt the hash with my private key (this process is also known as signing). To verify that the message is coming from me, the vendor will use my public key to decrypt the Hash and compare it with the unencrypted hash. If they match, the vendor can be confident that it came from me.
So how come my private key is used to encrypt the message..and how can public key decrypt the message? I thought Asymmetric keys doesn't allow that..! i.e Public Key always encrypts and private key always decrypts. Any explanations will be greatly appreciated..!
Encryption and signature are two different systems. In some ways, they work in opposite directions.
With public-key encryption, anybody can encrypt data with the public key. Only the owner of the private key can decrypt encrypted messages to recover the data.
With signatures, only the owner of the private key can sign messages. Anybody can use the public key to verify the signature of a message.
My understanding of Public/Private key is that data is always encrypted with the vendor's public key and they decrypt using their private key.
That's correct. But it only covers public-key encryption, not other uses of public-key cryptography such as signatures.
However, to validate that the message is really coming from me, I will compute the hash of the message and encrypt the hash with my private key (this process is also known as signing).
Actually, this process should only be known as signing. Calling it “encrypting with my private key” is very misleading: that's not the way it actually works. There is one popular type of keys (RSA) which can be used for both signature and encryption, but even with RSA, the signature and decryption mechanisms are different.
To verify that the message is coming from me, the vendor will use my public key to decrypt the Hash and compare it with the unencrypted hash. If they match, the vendor can be confident that it came from me.
That's not quite correct. Many signature algorithms are not deterministic. Verifying a signature is not done by reversing the signature process, but by making some slightly different calculations involving the signature, the message and the key.
So how come my private key is used to encrypt the message..and how can public key decrypt the message? I thought Asymmetric keys doesn't allow that..! i.e Public Key always encrypts and private key always decrypts. Any explanations will be greatly appreciated..!
The private key is used to sign the message, not to encrypt it. The public key is used to verify the signed message, not to decrypt it.
i found this link very helpful :
http://www.nusphere.com/products/library/ssl.htm
Wayback Machine archive from 2007 of the above nusphere link.
HTH
Ohad
EDIT
after 2.5 years, I see that the link is broken. So this one is good as well.
And in case it will be broken again in 2.5 years from today, here is the summary:
The Public Key is what its name suggests - Public. It is made
available to everyone via a publicly accessible repository or
directory. On the other hand, the Private Key must remain confidential
to its respective owner.
Because the key pair is mathematically related, whatever is encrypted
with a Public Key may only be decrypted by its corresponding Private
Key and vice versa.
Public Key Cryptography can therefore achieve Confidentiality. However
another important aspect of Public Key Cryptography is its ability to
create a Digital Signature.
The difference between symmetric and asymmetric encryption is only the existence of private and public keys.
Nevertheless in the common algorithms you can use the private key to encrypt messages which can be decrypted with the public key and you can also decrypt messages which are encrypted with the public key. So it is possible in both directions.