Create x509 certificate and encrypt lots of data - c#

I want to create an encrypted XML file. Encrypted as a whole.
I have one big class, which I serialize to a string. Then I convert it to bytes (f.e in one test case it takes 1128 bytes) and I want to encrypt those bytes.
I need to have a certificate which no admin user has access to, so I created my cert like this:
New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -FriendlyName "XD" -NotAfter
(Get-Date).AddYears(10) -KeyAlgorithm RSA -KeyLength 2048 -Subject "test"
Then in my C# app I get to that cert by .Subject and I want to encrypt my bytes using it. The problem is, that I get the exception with bad length message, which suggest, that I want to encrypt too many bytes with RSA.
Now I know I can use AES or something else, but I need to have this key in the certificate in the store, so no one except admin user, which creates that cert has access to it. And as I've read the documentation for New-SelfSignedCertificate - it cannot create a cert with f.e AES key.
So my question here would be: Is there a way to create a cert with a particular key algorithm which would be able to encrypt at least 2-3k bytes?

RSA can only encrypt messages that are smaller than the modulus of the key pair. Some bytes should be reserved for padding, and the exact number depends on the padding scheme you are using.
In practice, asymmetric algorithms like RSA are usually used for key transport, not directly for message encryption. If you have a long message, encrypt it with AES, using a random key. Then encrypt the AES key with RSA, using the public key of the message recipient.
Standards like TLS, PGP, and S/MIME use RSA in this way.

Related

How to decrypt string in c# or sql server using symmetric key

Below is my scenario
I receive encrypted value(using DBMS_CRYPTO.ENCRYPT_3DES_2KEY) from client in text file ( Encryptions done in Oracle)
I receive the key(AES192 30 character key) from client which is used for encryption.
I am using SQL Server 2012. How can i decrypt this value in SQL OR C#?
This essentially requires to follow below mentioned step:
Verify SQL Server Master Key
Create a Master Key Encryption password
Create a self signed certificate
A certificate is a digitally signed security object that contains a public (and optionally a private) key for SQL Server
Create Symmetric Key.
Encrypt the column(needs to be varbinary type)
To add records:
sample syntax:
OPEN SYMMETRIC KEY SymmetricKey1 DECRYPTION BY CERTIFICATE Certificate1;
-- Performs the update of the record
INSERT INTO dbo.test VALUES
(x, EncryptByKey(Key_GUID('SymmetricKey1'), CONVERT(varchar,'4545-58478-1245')));
GO
For step by step execution, follow this mssqltips article

Decrypting the DUKPT TDES encrypted code of a Magnetic stripe reader in C#?

I am developing application for Magnetic Stripe reader, and the encrypted code format is DUKPT TDES Algorithm so my question is,
How to decrypt the encrypted code using DUKPT-TDES alogorithm in C#?
if any sample library available please post here.
According to Wikipedia, DUKPT is a Key Management method or process for assigning a unique Key for encryption of each transaction to be encrypted. As such it is not an encryption method, just a way of getting the key to use in the encryption (in your case the encryption method is Triple DES).
You will either have to make your own process for DUKPT, or find out how to use the process of the appropriate provider. Using your own should be OK (but not a trivial task, I guess) unless someone other than you needs to be able to decrypt the encrypted data: they will then need a way of getting hold of the correct key.

Veryifying RSA signature using openssl_public_decrypt failing for .NET signed string

I am attempting to use X509Certificate2 and RSACryptoServiceProvider together with PHP OpenSSL commands to implement two-way mutual security.
It all seems to be fine sending a message from PHP to C#, RSACryptoServiceProvider on the .NET server can decrypt the message using it's own private key and verify the signature using the PHP server's public key.
But going the other way, .NET to PHP, is causing trouble using 'openssl_public_decrypt' to verify the signature of the .NET server. It just returns false. 'openssl_private_decrypt' works fine to decrypt the encrypted data with the PHP server's private key.
I created the RSA (2048)self-signed certificates for both servers using openssl (.key and .crt) and then created a .pfx to use as private key in .NET code.
I am wondering what is the problem here. I am using the default settings for the encryption/decryption on both the .NET and PHP servers. Are the encryption/decryption mechanisms not the same on the case when you have encrypted something with a .pfx? Or does openssl_public_decrypt expect a different encryption from what RSACryptoServiceProvider gives you?
Any help would be great, as I'm not really sure where the issue lies.
openssl_public_decrypt is pretty anal about the format of the public key and doesn't support as many padding schemes as openssl_private_decrypt does.
My recommendation: Use phpseclib, a pure PHP RSA implementation. An example:
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey('...'); // public key
$plaintext = '...';
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$ciphertext = $rsa->encrypt($plaintext);
$rsa->loadKey('...'); // private key
echo $rsa->decrypt($ciphertext);
?>
It supports a ton more key formats than OpenSSL does, from XML Signature formatted keys, to PuTTY keys, etc.

How to store the key used to encrypt files

I'm playing around with an app to backup files to "the cloud" :) and I want to encrypt the files before I store them. That part I have covered, but as this app will be monitoring folders for change and uploading the changed files I need to store the key that I use to encrypt the files with. The idea is that the user provides a password and a key is generated.
At the moment I'm using the .NET Framework to do the encryption. I'm using the RijndaelManaged class to encrypt/decrypt and the PasswordDeriveBytes class to get the key.
But how should I keep the key that is used for encrypting the files? I also want the program start to with Windows and not need to have the user enter their password again.
I'd recommend avoiding using asymmetric encryption for encryption of your files. Asymmetric encryption is significantly more expensive (computationally) than symmetric encryption algorithms of equal strength. For encrypting large files I'd recommend AES over RSA any day.
As to your question - the Data Protection API (DPAPI) Gaurav mentions is your best bet on Windows. How to: Use Data Protection
DPAPI offers ProtectedMemory and ProtectedData. The former allowing you to protect secrets in memory, the latter affords protection for secrets persisted to disk. The API takes care of encryption & decryption for you, and (depending on the specified scope) will protect your data from access/decryption by other users or on other machines.
To use DPAPI in your scenario, I'd recommend taking the users password, generating a symmetric encryption key (e.g. PasswordDeriveBytes), storing that using DPAPI and restricting access to the current user.
Your application can use that key to encrypt all uploads. Your application can obtain the key without re-prompting the user, and the key could be regenerated by the user on a new system.
One downside would be that a malicious application also executed by the same user could potentially obtain the secret key. To protect against this scenario additional entropy (effectively a salt) must be provided in Protect & Unprotect. However implementing this will likely stray from your objective - because now you'll need to prompt the user for something that seems an awful lot like a password.
Also: interesting reading:
You may also find this post from Backblaze an interesting read. Although they do not explain how they support your scenario (encrypted uploads that the cloud provider cannot decipher - only that they offer such a service):
http://blog.backblaze.com/2008/11/12/how-to-make-strong-encryption-easy-to-use/
Disclaimer: I am a satisfied Backblaze customer, but am in no other way affiliated with their service.
PS: Do take the time to mark acceptable answers. The community will reward you.
I suggest you to use asymmetric encryption like I described here. That will allow you to only have one single private key to protect (and backup) even while every file will be encrypted with a different symmetric key.
You can also let Windows (actually CryptoAPI) protect the key using a CspParameters (and the right flags) with the RSACryptoServiceProvider. Depending on your flags you can have the key will be available for the logged on user (so it gets as secure as the user login password).
DPAPI was designed to solve this challenge.
I concur with the DPAPI suggestion. Here's some code to demonstrate how to use the ProtectedData class. This isn't exactly germane for your exact scenario, but you can extrapolate.
byte[] GetEncryptionKey()
{
var path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
AppDomain.CurrentDomain.FriendlyName,
"nothing interesting... move along",
"top secret encryption key");
Debug.WriteLine("Encryption Key File: " + path);
var file = new FileInfo(path);
if (!file.Directory.Exists)
file.Directory.Create();
// determine if current user of machine
// or any user of machine can decrypt the key
var scope = DataProtectionScope.CurrentUser;
// make it a bit tougher to decrypt
var entropy = Encoding.UTF8.GetBytes("correct horse battery staple :)");
if (file.Exists)
{
return ProtectedData.Unprotect(
File.ReadAllBytes(path), entropy, scope);
}
// generate key
byte[] key;
using(var rng = RNGCryptoServiceProvider.Create())
key = rng.GetBytes(1024);
// encrypt the key
var encrypted = ProtectedData.Protect(key, entropy, scope);
// save for later use
File.WriteAllBytes(path, encrypted);
return key;
}

X509 Certificate multi-passwords?

I would like to know if x509 certificate's password allows multi-passwords per certificate - or just one?
And if it is possible, what scenario would it be applied?
Thanks for your time.
Because GnuPG is easily available to me, it'd be my tool of choice; each admin would create a public/private key pair and export the public portion:
gpg --gen-key
gpg --export --armor [keyid] > key_file_[admin_name]
Import all the public keys into the keyring of whoever 'owns' the unencrypted x509 cert:
cat key_file_* | gpg --import
Then encrypt the cert with all the keys:
gpg -r keyid1 -r keyid2 -r keyid3 ... -o encrypted_cert -e plaintext_cert
Now encrypted_cert can be decrypted by whoever has one of the private keys and that private key's passphrase:
gpg encrypted_cert
PGP could also do the job, and probably with only slight modifications to the commands here.
Because all this is doing is encrypting a single symmetric key multiple times, once to each public key (and storing the results in a file format prepared to handle multiple copies of the encrypted symmetric key), it would be easy enough to re-implement in whatever language you'd like, if your trial wrappers work well enough.
It allows just one password and it is used to secure private key in the certificate. If you want to access private key you must provide a password.

Categories

Resources