I am trying to encrypt a file when I save it to disk and I have looked at the Crypto namespace in C#, but am unsure how I should do it. Basically I need the ability for my program to be able to both encrypt and decrypt a file. The file is just an xml file that is serialized by my program, but it can contain sensitive data like connection strings for SQL servers. My clients want the ability to email these profiles to others and open them in our application to apply the settings to their system.
I tried the AES classes in the Crypto namespace, but I don't know where to store the IV and the key so that my program on another machine will be able to decrypt it.
In a typical scenario, the flow for handling something like this would go:
The IV is static and known to the client
The end machine generates an RSA keypair, and gives the public key only to the party sending the data (the XML file)
Your AES key is generated, and encrypted using the RSA public key and sent to the client, now only the client is able to obtain that AES key using the private key it generated previously.
You encrypt the data using the AES key you securely sent to the client earlier
This means that even if someone captured the complete data stream, they wouldn't be able to decrypt your data because they don't have the private key required to obtain the AES key.
Related
I have working code that will encrypt and decrypt a string provided to methods and this all works fine for when im storing a users entered password for convenience later.
However what I am trying to do is provide a password (encrypted) in the applications config file that allows users to pull data from an SQL server on the same domain.
Because I've used ProtectedData.Protect with DataProtectionScope.CurrentUser it has been encrypted using me as a key meaning users cannot decrypt this key, and DataProtectionScope.LocalMachine is also not applicable.
private static byte[] Entropy = { // Some arbitrary numbers };
public static string Encrypt(string _toEncrypt)
{
byte[] originalText = Encoding.Unicode.GetBytes(_toEncrypt);
byte[] EncryptedText = ProtectedData.Protect(originalText, Entropy, DataProtectionScope.CurrentUser);
return Convert.ToBase64String(EncryptedText);
}
public static string Decrypt(string _toDecrypt)
{
byte[] EncryptedText = Convert.FromBase64String(_toDecrypt);
byte[] OriginalText = ProtectedData.Unprotect(EncryptedText, Entropy, DataProtectionScope.CurrentUser);
return Encoding.Unicode.GetString(OriginalText);
}
Is there another way of doing this that allows for a password to be decrypted when required and be provided in its encrypted format for security reasons?
Since you're using app.config for your configuration file, you can actually use the aspnet_regiis utility to encrypt sections of the file.
It's been a while since I've had to do this, but there are some resources on the internet if you do some searching (for example). But, if I recall correctly the steps are basically:
Temporarily rename your app.config to web.config because
aspnet_regiis will only work on web.config.
Open a Developer Command Prompt (might need to do it as an administrator).
Run aspnet_regiis -pef <the section you're encrypting> <path to your web.config>. The path should just be the folder where the configuration file can be found, don't include web.config.
Rename your configuration file back to app.config.
This will need to be run on the server or machine hosting your application. If your application is not running from a single server things become more complicated as you will have to export the key, and import it to every computer running the application. This article contains the steps:
Create a machine-level RSA Key Container (1 time step)
Exporting the Custom RSA Encryption Key (1 time step)
Importing the Certificate (1 time step - per machine)
Adding Permissions to the Certificate (1 time step - per machine)
Encrypting the Configuration Section
Decrypting the Configuration Section
You don't actually need to do any sort of special decryption in your application. The configuration system will handle that for you automatically.
I am trying web.config encryption for server deployment.
I am using the aspnet_regiis.exe for encryption of the connection string.
In this project there are multiple datasets for the database calls.
how can I set decryption for all these datasets from one place as I cannot set decryption for each of the datasets nor can I keep the encrypted file during development.
after encryption the
<connectionstring></connectionstring>
gets converted to
<encrypteddata></encrypteddata>
so application crashes at the
((global::System.Data.SqlClient.SqlCommand)(this._commandCollection[0])).Connection = new global::System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString)
in the typed dataset as it is not able to ApplicationServices as now it is encrypted in the encrypted data
I have a smartcard with a card reader and I decide to implement a client certificate in the latter.
The private key being stored in the card and the public key is stored in the server.
The application scenario is something like this:
application send frames to the Linux server
Linux server answer with a ramdom number
application read private key from (smartcard or pem file) and encrypt received random number and send the result to the server.
server try to decrypt the sent encrypted string via public key (pem file stored in the server) => if succeed access is granted else access is denied.
In my application, there is a mode of certificate authentication (static file .pem) and also uses the private key (also static .pem). I used openssl-net functions such as FromPrivateKey(string pem, string password) and PrivateEncrypt(byte[] msg, RSA.Padding padding) for read private key and encrypt data to send to the server.
The problem that is needed, is that I have no a priori way to export my private key in my smartcard since my pem file.
So after much research I understood that I should use instead of these functions type functions: "ENGINE_load_private_key" with engine "pkcs11."
So I have seen several examples of openssl configuration (eg http://openssl.6102.n7.nabble.com/Private-Key-from-Windows-Cert-Store-td20720.html) with pkcs11 (opensc, engine_pkcs11. so etc. ..) the trouble is that these configurations are for Linux.
Indeed, my need is to develop a client application windows WPF (written in C #) that can read the private key from the smartcard or from a PEM file.
In a client/server model
We have a RSACryptoServiceProvider key created using a well known "container name" at the startup code, and set a rule on it to Allow Generic Read, and persist the public key into a database. The clients connecting to the server, send sensitive information encrypted with the public key and the server decrypts it using the private key.
However, over time, we are observing that the public key in the crypto store (it's a machine level crypto store at %ProgramData%\Microsoft\Crypto\RSA\Machine Keys goes out of sync with the stored public key in the database) and our clients stop communicating with the server.
Are there any possible reasons as to how this happens ? Is there a way we can detect it when this happens ?
We need to PGP encrypt files and send them over FTP to a third party. The files are encrypted with the DH/DSS public key of the third party and signed with our private key.
The third party have our public key and their own private key. The encryption/decryption works, but the third party are getting warnings when they try to verify our signature.
When we try to decrypt and verify similarly encrypted files using PGP Desktop the files verify without warning.
The third party are using "McAfee E-Business Server"
The exact warning is:
WARNING: Bad signature, doesn't match file contents!
Bad signature from user "users name"
The code is a little involved, but I posted it on my blog. I can post it here instead of a link if that is more appropriate.
Any insight as to how to solve this issue is appreciated.
While I can't give a thorough explanation as to the details of the problem, here is a solution that works.
First of all it seems that the different PGP implementations are very sensitive to which program was used to genereate the keys in use.
The failing scenario:
Create keys in PGP Desktop (RSA v4, 2048/2048)
Encrypt in BouncyCastle (DH/DSS, Elgamal)
Sign in BouncyCastle (With the RSA key)
Decryption and signature verification success in PGP Desktop.
Decryption success but signature verification fails in McAfee Business Server.
In order to make McAfee Business Server succeed in verifying the keys either create the keys in BouncyCastle using the code from the BouncyCastle source code.(Org.BouncyCastle.Bcpg.OpenPgp.Examples.RsaKeyRingGenerator)
This code can be changed if you need specific key properties.
Another alternative is to use McAfee Business Server to generate the keys. For that you need access to the software. I did my tests with a trial version. (Which by the way was a pain in the neck to get up and running)
Update: I did all my tests on E-Business Server 8.5.3 (trial). I reached the point where I could encrypt and sign in Bounty and decrypt and verify in E-Business Server. Turns out the third party are using E-Business Server 7.0 which refused to verify the signature.
In order to get everything working we needed to create V3 signatures.
We changed from:
PgpSignatureGenerator pgpSignatureGenerator = new PgpSignatureGenerator(m_encryptionKeys.SecretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
to
PgpV3SignatureGenerator pgpV3SignatureGenerator = new PgpV3SignatureGenerator(m_encryptionKeys.SecretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);