Is it secure mechanism of sharing data? - algorithm

I need to share a file with some users. Using the way described below. Is it secure to share keys?
I have a data file.
I will encrypt a file, using any algorithm(GPG, OpenSSL).
Before encrypt I create keys private and public.
Then I upload a file to public storage.
If someone will find a file, and download it, he couldn't read encrypted file.
If I share my keys (private or public key?) with someone whom I want to share, he could decrypt use the same algorithm with my key.
Is it secure to share a key to decrypt a file?

If you wanted to share an encrypted file with someone, that intended recipient would give you their public key. You would encrypt it with the recipient's public key and only the recipient would be able to decrypt it with their private key.
Generally, no, it is not secure to share a key.
Other things to consider:
Public/Private keys can only encrypt a small amount of data by themselves. Generally they are used to encrypt symmetric keys that are used to encrypt/decrypt the payload. Using GPG etc would likely generate a "file" for you that has the symmetric key encrypted with the recipient's public key as well as the symmetrically encrypted payload. The recipient decrypts with their private key.
When you get your intended recipient's public key, how can you be sure the public key came from your recipient? Read up on the concept of man-in-the-middle for some things to consider.

Related

Xamarin forms app: how to digitally sign using private key from keystore

I want to use asymmetric key pairs to sign/verify data sent from an Xamarin forms smartphone app to a web service.
I have an Xamarin forms smartphone app targeted at Android and iOS devices. The client on the device connects through a web service to a database and, on successful login, retrieves and sends data. Currently the user logs in, providing username and password. The password is hashed and the database user table is searched for the combination of the username and password hash. If this combination is found then the user is deemed to be legitimate and information can be retrieved and sent.
I now want to introduce another layer of security, so that each device that installs the app would need, additionally, a private key. This key would be used to produce a digital signature or hash of data sent up to the web service. When the web service receives the request, it will use the corresponding public key of the key pair to verify the signature, and only allow the request through if the signature is verified. From time to time, I may want to eliminate the user base and start afresh and I was thinking that I could do this easily by creating a new asymmetric key pair and sending the new private key out to each user whom I wanted to be able to use the system while also changing the corresponding public key on the web service to the new one. This way anyone still using the old private key would not gain access. The difficulty I have found with this approach is that I don’t know how to get a new key on to the user's device and, having done that, I don’t know how to get access to this key in the app’s code in order to create the digital hash. I have tried experimentally to look at the key store, but I don’t seem to be able to do that on an iPhone the way I can on the PC, so my question, at its simplest is, how do I get a private key onto an iPhone or an Android phone and, having got it on there, how do I get access to it in code in order to use it to generate a digital hash. Of course, I could just use symmetric encryption, and pass a password to the user base which could then be used in code to encrypt some mutually agreed piece of text and the web service, on receiving it, would use the same password to decrypt it. I just thought that the asymmetric key pair approach was a more elegant, and, in the end, more robust solution. The other point is that I want to use the .Net System.Security.Cryptography classes only, ie no third party code if possible.

Offline check a token's validity against user alteration

I have a question about protecting data against an untrusted end-user in the following scenario:
Basic feature to implement:
User logs into desktop app using username and password in order to have access to a subscription based software
The server respond with an encrypted token having a validity (30 days for example) and a Hardware Identifier specific for that one machine for which the user is now entitled. The server also responds with a public key with which the token above can be decrypted/checked
Every time the user launch the desktop app, if we are in an offline scenario we check the validity of the token by decrypting it with the public key, and then we can check if it is still within the validity period, and if it is on the correct Hardware as well (i.e. if the user did not just copy the encrypted files on a different machine and try to use the same account on more computers simultaneously)
Problem:
The scenario above has no protection against an untrusted user.
Example of possible attack:
The user decrypts the token using the public key
He now edits the token and sets a new Hardware Identifier, for the new machine he wants to copy the tokens
He edits the expiring date to 31.12.2099 for example
He generates his own private-public pair of keys
He encrypt the token again with his own private key
Now he can transport the encrypted token together with his own public key on the new machine, and as soon as he launches the desktop app in an offline scenario, the app has no way to tell that the token has been altered. It checks the authenticity of the token, but it can't check that the public key has been corrupted as well.
Every asymmetric encryption approach assumes that the end-user is trustable. For example when signing an app with a certificate, we assume that the user has no intention in attacking the offline trusted root certificates.
A solution I avoid would be to encrypt the private key or the public key within the code, but:
That is very very unsafe
That is not flexible in case you want to update the keys
It can be reversed engineered
After studying cryptography for a while I never realized that this scenario is so unsafe. Now I am wondering how a lot of already existing apps work in this scenario without exposing themselves to this so easy attack?
Thank you!

How can user access any of his messages after RSA encryption?

I am planning to build a site to exchange messages securely using the Rsa algorithm and the end-to-end encryption. Question here: As we know from RSA encryption, if User1 wants to send a message to User2. User 1 requests User2's public key and encrypts the message.
User 2 can learn the message’s content by decrypting it using his private key.
Well ... how will the first user be able to access his message after it is encrypted?
It was stored in the database in an encrypted form.
There is an option to solve the problem but I think it is impractical.
When User1 creates a message to send to User2, he encrypts it with his public key and keeps it in the database
Then he encrypts the original message with User 2's public key and also saves it in the database.
Do you have any alternative solutions or suggestions?
thnx
The messages between User 1 and User 2 can be encrypted using a symmetric cipher with a key which they both share and only use for messages to each other. The key itself can be stored encrypted with User 1's public key, and separately stored encrypted with User 2's public key, so that each user is able to access the symmetric key to decrypt messages they sent as well as messages they received.

Detect the existence of a private key

I 'm trying to present the user a dialog to pick a certificate. Originally I used CryptUIDlgSelectCertificateFromStore with the "MY" store, but this results in picking all the certificates, where I only want the user to select between the
certificates that have private keys.
For that reason, I create a new memory store and store only the certificates for which a private key exists. I can use CryptAcquireCertificatePrivateKey to get a private key of a certificate, but this may result in a dialog box requesting a PIN for example. I don't want to use the CRYPT_ACQUIRE_SILENT_FLAG because a provider might want to show information on the key (not necessarily a pin or a smart card prompt).
Is there a way to know that there is a private key without actually acquiring it?
Thanks.

Public Key signing/verification

I'm developing an application to manage file and email encryption using (primarily) PKI. I have a Public Keyring with a list of contacts and their Public Keys.
Referring back to the olden days when I used PGP, I recall a requirement to sign public keys with your Private Key.
Is this a necessity on PKI and if so, what does this signing achieve? Is it bad practice to simply hold a list/database of people's names (and email) and their Public Key? Surely if their public key is - in any way - tampered with the encryption would fail and as you choose who you're sending or sharing the encrypted data with, even if a 'successful tamper' went unnoticed, the encrypted data wouldn't end up in the wrong hands anyway?
The whole thing about signing a public key with a private key is useful when you have a dedicated key-pair that you use only for signing, and then other key-pairs that you use for encrypting. This dedicated key-pair is your "trusted" key-pair that is somehow known to be legitimately attached to you (often by having it signed by a certificate authority or by having many trusted people sign that they have verified it's connection to you.)
You use this "trusted" private key to sign your not-quite-as-trusted public key. This way, people can un-sign/decrypt your new public-key with your trusted public-key. This is only mathematically possible if it was signed by your trusted private-key.
This process helps people to be sure that this new public-key actually belongs to you.

Resources