Skip to main content

Use X509 certificate to encrypt and decrypt

1. To make a test certificate, use the makecert.exe tool
makecert -n "CN=My Company" -ss "MyCompany.com" -pe -sr LocalMachine -sky Exchange test.cer
Here the -sky Exchange parameter is very important, without this, the generated certificate can only be used for signing, but not for encrypting/decrypting.


2. Write C# code as following:
    public class CertificateSSO
    {
        private X509Certificate2 GetCertificate()
        {
            X509Store store = new X509Store("
MyCompany.com", StoreLocation.LocalMachine);
            store.Open(OpenFlags.OpenExistingOnly);
            X509Certificate2 cert = store.Certificates.Find(X509FindType.FindBySubjectName, "My Company", false)[0];
            store.Close();
            return cert;
        }

        public string Encrypt(string strPlainText)
        {
            X509Certificate2 cert = GetCertificate();
            using (RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PublicKey.Key)
            {
                return Convert.ToBase64String(provider.Encrypt(UTF8Encoding.UTF8.GetBytes(strPlainText), false));
            }
        }

        public string Decrypt(string strBase64CipherText)
        {
            X509Certificate2 cert = GetCertificate();
            using (RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PrivateKey)
            {
                byte[] arrPlainText = provider.Decrypt(Convert.FromBase64String(strBase64CipherText), false);
                return UTF8Encoding.UTF8.GetString(arrPlainText, 0, arrPlainText.Length);
            }
        }

        public string Sign(string strTextToSign)
        {
            X509Certificate2 cert = GetCertificate();
            using (RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PrivateKey)
            {
                return Convert.ToBase64String(provider.SignData(UTF8Encoding.UTF8.GetBytes(strTextToSign), new SHA1CryptoServiceProvider()));
            }
        }

        public bool VerifySignature(string strOriginalText, string strSignature)
        {
            X509Certificate2 cert = GetCertificate();
            using (RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PrivateKey)
            {
                 return provider.VerifyData(UTF8Encoding.UTF8.GetBytes(strOriginalText), new SHA1CryptoServiceProvider(), Convert.FromBase64String(strSignature));
            }
        }


        public string ExportPublicKey()
        {
            X509Certificate2 cert = GetCertificate();


            // RawData is byte array holding ASN.1 encoded key
            return Convert.ToBase64String(cert.PublicKey.EncodedKeyValue.RawData);
        }

        public string EncryptWithPublicKey(string strPublicKey, string strPlainText)
        {
            //
"1.2.840.113549.1.1.1" is the id for RSA
            Oid oid = new Oid("1.2.840.113549.1.1.1");
            AsnEncodedData keyValue = new AsnEncodedData(Convert.FromBase64String(strPublicKey));
            AsnEncodedData keyParam = new AsnEncodedData(new byte[] { 05, 00 });    // 05, 00 sequence means NULL in ASN.1
            PublicKey pubKey = new PublicKey(oid, keyParam, keyValue);
            using (RSACryptoServiceProvider provider = (RSACryptoServiceProvider)pubKey.Key)
            {
                return Convert.ToBase64String(provider.Encrypt(UTF8Encoding.UTF8.GetBytes(strPlainText), false));
            }
        }
    }

3. How to remove certificate store from certificate snap-in:
To remove certificate with the corresponding certificate store, you have to export the certificate with checked "Delete the private key if export successful" option.

Comments

Popular posts from this blog

Manage IIS 7 remotely using PowerShell and AppCmd

We can use  Windows PowerShell remoting features  to manage IIS 7 websites remotely.  Currently, remoting is supported on Windows Vista with Service Pack 1 or later, Windows 7, Windows Server 2008, and Windows Server 2008 Release 2.  Start Windows PowerShell as an administrator by right-clicking the Windows PowerShell shortcut and selecting Run As Administrator .  Enable PowerShell Remoting with Enable-PSRemoting -Force Starting a Remote Session using:  Enter-PSSession -ComputerName <COMPUTER> -Credential <USER> Now the PowerShell connected to the remote server. Any commands issued with work against the remote server. We can use the Appcmd.exe command line tool to manage remote server just as what we do locally. For example, to add an application pool: c:\windows\system32\inetsrv\appcmd add apppool /name:"Contoso" /managedPipelineMode:Integrated /managedRuntimeVersion:"v4.0" /enable32BitAppOnWin64:true To change application pool for a

X509Certificate2: The system cannot find the file specified.

When I use the new X509Certificate2(fileName, password, X509KeyStorageFlags.DefaultKeySet) to create certificate from certificate file containing private key in my web application, I got following error message: System . Security . Cryptography . CryptographicException : The system cannot find the file specified . at System . Security . Cryptography . CryptographicException . ThrowCryptogaphicException ( Int32 hr ) at System . Security . Cryptography . X509Certificates . X509Utils . _LoadCertFromBlob ( Byte [] rawData , IntPtr password , UInt32 dwFlags , Boolean persistKeySet , SafeCertContextHandle & pCertCtx ) at System . Security . Cryptography . X509Certificates . X509Certificate . LoadCertificateFromBlob ( Byte [] rawData , Object password , X509KeyStorageFlags keyStorageFlags ) at System . Security . Cryptography . X509Certificates . X509Certificate2 .. ctor ( Byte [] rawData , String password , X509KeyStorageFlags keyStorageFlags ) In orde

Entity framework code first error: OriginalValues cannot be used for entities in the Added state

When I was using Entity framework code first, I encountered an error when I tried to create an entity into database. The entity is: [ Table (" EmployeeProfile ")]     public partial class EmployeeProfile     {         [ Key ]         [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]         public int EmployeeProfileID { get; set; }         [ ForeignKey ("Employee")]         public int EmployeeID { get; set; }         public virtual Employee Employee { get; set; }         [ ForeignKey (" Profile ")]         public int ProfileID { get; set; }         public virtual Profile Profile { get; set; }         [ Required ]         [ StringLength (255)]         public string ProfileValue { get; set; }     } When creating the entity, some entities have the ProfileValue="", this causes the EntityValidationException with the detailed message " OriginalValues cannot be used for entities in the Added state ". I want to allow the Prof