|
security
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Having problem with Encryption using CryptoAPIWhen I run this program and try to encrypt the file using the "Encrypt" button, the file gets encrypted. But every time i do encrypt, I get a different output. As per my knowledge of the cryptography, every time I encrypt same data using the same key, I should get the same output. I want to use the key imported into my local store (in this case the store name is ""). Any help is appreciated. Thanks //------------------------------------------------------------------------------------------- using System; using System.IO; using System.Reflection; using System.Text; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Drawing; using System.Security.Cryptography.X509Certificates; using System.Runtime.InteropServices; using System.Security.Cryptography; namespace EncryptDecrypt { } public sealed class CERTPROPS_INFO { public CERTPROPS_INFO(byte[] hash, string certsubjname) { this.sha1hash = hash; this.SubjectNameCN = certsubjname; } public byte[] Hash { get { return sha1hash; } } public String Name { get { return SubjectNameCN; } } private byte[] sha1hash; private String SubjectNameCN; } public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.ComponentModel.Container components = null; public Form1() { InitializeComponent(); } protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.SuspendLayout(); // button1 this.button1.Location = new System.Drawing.Point(72, 40); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(128, 48); this.button1.TabIndex = 0; this.button1.Text = "Encrypt"; this.button1.Click += new System.EventHandler(this.button1_Click); // button2 this.button2.Location = new System.Drawing.Point(72, 120); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(128, 40); this.button2.TabIndex = 1; this.button2.Text = "Decrypt"; this.button2.Click += new System.EventHandler(this.button2_Click); // Form1 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.AddRange(new System.Windows.Forms.Control[] { this.button2, this.button1}); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion /// The main entry point for the application. [STAThread] static void Main() { Application.Run(new Form1()); } public byte[] Encrypt(byte[] data) { byte[] rawBuffer=data; byte[] encBuffer=null; // Length of the string to be encrypted uint bufLength= (uint)rawBuffer.Length; // Initialize the handle to Public key BLOB. IntPtr pPublicKeyBlob = IntPtr.Zero; // Handle to the certificate store (MyStore) IntPtr hSysStore; // Open the system store hSysStore = EncryptDecrypt.Wincrypt.CertOpenSystemStore(IntPtr.Zero, EncryptDecrypt.Wincrypt.MyStore) ; // MyStore // Handle to the certificate IntPtr pDesiredCert=IntPtr.Zero; // Finding the certificate in store for the using subject string "administrator" // This function returns handle to the certificate pDesiredCert = EncryptDecrypt.Wincrypt.CertFindCertificateInStore(hSysStore, EncryptDecrypt.Wincrypt.X509_ASN_ENCODING, 0, EncryptDecrypt.Wincrypt.CERT_FIND_SUBJECT_STR, "administrator", pDesiredCert); //administrator if(pDesiredCert!=IntPtr.Zero) { Console.WriteLine("The desired certificate was found. \n"); } else { Console.WriteLine("Could not find the desired certificate.\n"); } // Handle to particular key container within CSP IntPtr hProv = IntPtr.Zero; // The CryptAcquireContext function is used to acquire a handle to // a particular key container within a particular cryptographic // service provider (CSP). // 'slcchander512' is the name of the container which contains the key // pairs for the requested certificate.[Specified while requesting for // administrator] if (!EncryptDecrypt.Wincrypt.CryptAcquireContext( ref hProv, // Handle to be acquired "slcchander512", // Key Container's name null, // Name of the CSP -----default is null ----EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, EncryptDecrypt.Wincrypt.PROV_RSA_FULL, //Specifies the type of provider to acquire. The PROV_RSA_FULL provider type supports both digital signatures and data encryption 0 )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT { Console.Write("CryptAcquireContext failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // The CryptSetProvParam function customizes the operations of a cryptographic // service provider (CSP). This function is commonly used to set a security // descriptor on the key container associated with a CSP to control access to // the private keys in that key container. if(!EncryptDecrypt.Wincrypt.CryptSetProvParam( hProv, EncryptDecrypt.Wincrypt.PP_CLIENT_HWND, EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, 0)) { Console.WriteLine(Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // To acquire context again with Provider's name if (EncryptDecrypt.Wincrypt.CryptAcquireContext( ref hProv, "slcchander512", EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, EncryptDecrypt.Wincrypt.PROV_RSA_FULL, 0 )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT { Console.Write("CryptAcquireContext failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // Import the public key information from the certificate context // into a key container by passing the pointer to the // SubjectPublicKeyInfo member of the CERT_INFO structure // into CryptImportPublicKeyInfoEx. // An Additional byte offset, Adding to the pointer before read IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(pDesiredCert, 12); // For public key subject pointer, adding the integer number to the // certificate handle IntPtr pSubjectPublicKeyInfo = (IntPtr)(pDesiredCert.ToInt32() + 56); // Handle to the public key IntPtr hKey=IntPtr.Zero; // Getting the handle of one of a user's two public/private key pairs. if(!EncryptDecrypt.Wincrypt.CryptGetUserKey( hProv, EncryptDecrypt.Wincrypt.AT_KEYEXCHANGE, ref hKey)) { Console.Write("CryptGetUserKey failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // Now that the key is imported into a key container. // CryptExportKey is used to export the public key to the PUBLICKEYBLOB // format. // Gets the size of the buffer needed to hold the PUBLICKEYBLOB structure. // Length for public key uint dwDataLen = 0; //Handle to the Exported key (public key) IntPtr hExpkey= IntPtr.Zero; if (!EncryptDecrypt.Wincrypt.CryptExportKey( hKey, hExpkey, EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, 0, pPublicKeyBlob, ref dwDataLen)) { Console.WriteLine("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } pPublicKeyBlob = Marshal.AllocHGlobal((int)dwDataLen); // Then export the public key into the PUBLICKEYBLOB format by passing length. if (!EncryptDecrypt.Wincrypt.CryptExportKey( hKey, hExpkey, EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, 0, pPublicKeyBlob, ref dwDataLen)) { Console.WriteLine("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // Get the public exponent. // The public exponent is located in bytes 17 through 20 of the // PUBLICKEYBLOB structure. byte[] Exponent = new byte[4]; // A 32-bit signed integer equal to the value of this instance Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 16), Exponent, 0, 4); // Reverse the byte order. Array.Reverse(Exponent); // Get the length of the modulus. // To do this extract the bit length of the modulus from the PUBLICKEYBLOB. // The bit length of the modulus is at bytes 13 through 17 of the PUBLICKEYBLOB. int BitLength = Marshal.ReadInt32(pPublicKeyBlob, 12); // Get the modulus. The modulus starts at the 21st byte of the // PUBLICKEYBLOB structure and is BitLengh/8 bytes in length. // byte[] Modulus = new byte[BitLength / 8]; byte[] Modulus = new byte[BitLength / 8]; Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 20), Modulus, 0,BitLength / 8); //stop now Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 4), Modulus, 0,BitLength / 8); Array.Reverse(Modulus); // Reverse the byte order. // Performs asymmetric encryption and decryption using the implementation of the // RSA algorithm provided by the cryptographic service provider (CSP) // Put the modulus and exponent into an RSAParameters object. RSAParameters rsaparms = new RSAParameters(); rsaparms.Exponent = Exponent; rsaparms.Modulus = Modulus; // Import the modulus and exponent into an RSACryptoServiceProvider // object via the RSAParameters object. RSACryptoServiceProvider rsacsp = null; rsacsp = new RSACryptoServiceProvider(512,GetCSPParams()); rsacsp.ImportParameters(rsaparms); encBuffer=rsacsp.Encrypt(rawBuffer,false); Cleanup: if (pDesiredCert != IntPtr.Zero) EncryptDecrypt.Wincrypt.CertFreeCertificateContext(pDesiredCert); if (hProv != IntPtr.Zero) EncryptDecrypt.Wincrypt.CryptReleaseContext(hProv, 0); if (pPublicKeyBlob != IntPtr.Zero) Marshal.FreeHGlobal(pPublicKeyBlob); return encBuffer; } enum CheckTrue { first, second } public byte[] Encrypt(byte[] data,bool bchk) { // byte array of plain text to be encrypted byte[] rawBuffer=data; // byte array of encrypted text will be generated in this array byte[] encBuffer=null; // Length of the string to be encrypted uint bufLength= (uint)rawBuffer.Length; // Initialize the handle to Public key BLOB. IntPtr pPublicKeyBlob = IntPtr.Zero; // Handle to the certificate store (MyStore) IntPtr hSysStore; // Open the system store hSysStore = EncryptDecrypt.Wincrypt.CertOpenSystemStore(IntPtr.Zero, EncryptDecrypt.Wincrypt.MyStore) ; // MyStore // Handle to the certificate IntPtr pDesiredCert=IntPtr.Zero; // Finding the certificate in store for the using subject string "administrator" // This function returns handle to the certificate pDesiredCert = EncryptDecrypt.Wincrypt.CertFindCertificateInStore(hSysStore, EncryptDecrypt.Wincrypt.X509_ASN_ENCODING, 0, EncryptDecrypt.Wincrypt.CERT_FIND_SUBJECT_STR, "administrator", pDesiredCert); //administrator if(pDesiredCert!=IntPtr.Zero) { Console.WriteLine("The desired certificate was found. \n"); } else { Console.WriteLine("Could not find the desired certificate.\n"); } // Handle to particular key container within CSP IntPtr hProv = IntPtr.Zero; // The CryptAcquireContext function is used to acquire a handle to // a particular key container within a particular cryptographic // service provider (CSP). // 'slcchander512' is the name of the container which contains the key // pairs for the requested certificate.[Specified while requesting for // administrator] if (!EncryptDecrypt.Wincrypt.CryptAcquireContext( ref hProv, // Handle to be acquired "slcchander512", // Key Container's name null, // Name of the CSP -----default is null ----EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, EncryptDecrypt.Wincrypt.PROV_RSA_FULL, //Specifies the type of provider to acquire. The PROV_RSA_FULL provider type supports both digital signatures and data encryption 0 )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT { Console.Write("CryptAcquireContext failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // The CryptSetProvParam function customizes the operations of a cryptographic // service provider (CSP). This function is commonly used to set a security // descriptor on the key container associated with a CSP to control access to // the private keys in that key container. if(!EncryptDecrypt.Wincrypt.CryptSetProvParam( hProv, EncryptDecrypt.Wincrypt.PP_CLIENT_HWND, EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, 0)) { Console.WriteLine(Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // To acquire context again with Provider's name if (EncryptDecrypt.Wincrypt.CryptAcquireContext( ref hProv, "slcchander512", EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, EncryptDecrypt.Wincrypt.PROV_RSA_FULL, 0 )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT { Console.Write("CryptAcquireContext failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // Import the public key information from the certificate context // into a key container by passing the pointer to the // SubjectPublicKeyInfo member of the CERT_INFO structure // into CryptImportPublicKeyInfoEx. // An Additional byte offset, Adding to the pointer before read IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(pDesiredCert, 12); // For public key subject pointer, adding the integer number to the // certificate handle IntPtr pSubjectPublicKeyInfo = (IntPtr)(pDesiredCert.ToInt32() + 56); // Handle to the public key IntPtr hKey=IntPtr.Zero; // Getting the handle of one of a user's two public/private key pairs. if(!EncryptDecrypt.Wincrypt.CryptGetUserKey( hProv, EncryptDecrypt.Wincrypt.AT_KEYEXCHANGE, ref hKey)) { Console.Write("CryptGetUserKey failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // The CryptImportPublicKeyInfoEx function imports public key // information into the CSP and returns a handle of the public key. // Now that the key is imported into a key container. // CryptExportKey is used to export the public key to the PUBLICKEYBLOB // format. // Gets the size of the buffer needed to hold the PUBLICKEYBLOB structure. // Length for public key uint dwDataLen = 0; //Handle to the Exported key (public key) IntPtr hExpkey= IntPtr.Zero; if (!EncryptDecrypt.Wincrypt.CryptExportKey( hKey, hExpkey, EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, 0, pPublicKeyBlob, ref dwDataLen)) { Console.WriteLine("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } pPublicKeyBlob = Marshal.AllocHGlobal((int)dwDataLen); // Then export the public key into the PUBLICKEYBLOB format by passing length. if (!EncryptDecrypt.Wincrypt.CryptExportKey( hKey, hExpkey, EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, 0, pPublicKeyBlob, ref dwDataLen)) { Console.WriteLine("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // Get the public exponent. // The public exponent is located in bytes 17 through 20 of the // PUBLICKEYBLOB structure. byte[] Exponent = new byte[4]; // A 32-bit signed integer equal to the value of this instance //stop now Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 164), Exponent, 0, 4); Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 16), Exponent, 0, 4); // Reverse the byte order. Array.Reverse(Exponent); // Get the length of the modulus. // To do this extract the bit length of the modulus from the PUBLICKEYBLOB. // The bit length of the modulus is at bytes 13 through 17 of the PUBLICKEYBLOB. int BitLength = Marshal.ReadInt32(pPublicKeyBlob, 12); //stop now int BitLength = 64 * 8; // Get the modulus. The modulus starts at the 21st byte of the // PUBLICKEYBLOB structure and is BitLengh/8 bytes in length. // byte[] Modulus = new byte[BitLength / 8]; byte[] Modulus = new byte[BitLength / 8]; Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 20), Modulus, 0,BitLength / 8); Array.Reverse(Modulus); // Reverse the byte order. // Performs asymmetric encryption and decryption using the implementation of the // RSA algorithm provided by the cryptographic service provider (CSP) // Put the modulus and exponent into an RSAParameters object. RSAParameters rsaparms = new RSAParameters(); rsaparms.Exponent = Exponent; rsaparms.Modulus = Modulus; // Import the modulus and exponent into an RSACryptoServiceProvider // object via the RSAParameters object. RSACryptoServiceProvider rsacsp = null; rsacsp = new RSACryptoServiceProvider(512,GetCSPParams()); rsacsp.ImportParameters(rsaparms); encBuffer=rsacsp.Encrypt(rawBuffer,false); Cleanup: if (pDesiredCert != IntPtr.Zero) EncryptDecrypt.Wincrypt.CertFreeCertificateContext(pDesiredCert); if (hProv != IntPtr.Zero) EncryptDecrypt.Wincrypt.CryptReleaseContext(hProv, 0); if (pPublicKeyBlob != IntPtr.Zero) Marshal.FreeHGlobal(pPublicKeyBlob); return encBuffer; } // This function takes a encrypted byte array and returns decrypted data public byte[] Decrypt(byte[] data) { //Byte array containing encrypted data byte[] rawBuffer=data; //Byte array for containing decrypted data byte[] decBuffer=null; //handle to the key container within CSP provider IntPtr hProv = IntPtr.Zero; IntPtr hExpkey = IntPtr.Zero; //Length of the data to be encrypted uint dataLength = (uint)data.Length; //Handle to the private key blob IntPtr pPrivateKeyBlob = IntPtr.Zero; //Handle to the private key IntPtr hPrivateKey=IntPtr.Zero; //Handle to the Certificate key IntPtr hSysStore; //Opening certificate store hSysStore = EncryptDecrypt.Wincrypt.CertOpenSystemStore(IntPtr.Zero, EncryptDecrypt.Wincrypt.MyStore) ; // MyStore //Handle to the certificate thru which private key is to be retrieved IntPtr pDesiredCert=IntPtr.Zero; //Retrieves the certificate handle pDesiredCert = EncryptDecrypt.Wincrypt.CertFindCertificateInStore(hSysStore, EncryptDecrypt.Wincrypt.X509_ASN_ENCODING, 0, EncryptDecrypt.Wincrypt.CERT_FIND_SUBJECT_STR, "administrator", pDesiredCert); //administrator if(pDesiredCert!=IntPtr.Zero) { Console.WriteLine("The desired certificate was found. \n"); } else { Console.WriteLine("Could not find the desired certificate.\n"); } // The CryptAcquireContext function is used to acquire a handle to // a particular key container within a particular cryptographic // service provider (CSP). // 'slcchander512' is the name of the container which contains the key // pairs for the requested certificate.[Specified while requesting for // administrator] if (!EncryptDecrypt.Wincrypt.CryptAcquireContext( ref hProv, "slcchander512", null, EncryptDecrypt.Wincrypt.PROV_RSA_FULL, 0 )) { Console.Write("CryptAcquireContext failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } //Retrieves a handle of one of a user's two public/private key pairs. if (!EncryptDecrypt.Wincrypt.CryptGetUserKey( hProv, EncryptDecrypt.Wincrypt.AT_KEYEXCHANGE, ref hPrivateKey)) { Console.Write("CryptGetUserKey failed :" + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } //Holds length of the private key blob uint dwDataLen = 0; //The CryptExportKey function exports a cryptographic key or a key pair // from a cryptographic service provider (CSP) in a secure manner. //Get the length of BLOB first time if (!EncryptDecrypt.Wincrypt.CryptExportKey( hPrivateKey, hExpkey, EncryptDecrypt.Wincrypt.PRIVATEKEYBLOB, 0, IntPtr.Zero , ref dwDataLen)) { Console.WriteLine("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // Then export the private key into the PRIVATEKEYBLOB format. pPrivateKeyBlob = Marshal.AllocHGlobal((int)dwDataLen); if (!EncryptDecrypt.Wincrypt.CryptExportKey( hPrivateKey, hExpkey, EncryptDecrypt.Wincrypt.PRIVATEKEYBLOB, 0, pPrivateKeyBlob, ref dwDataLen)) { Console.WriteLine("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString()); goto Cleanup; } // Get the public exponent. // The private exponent is located in bytes 17 through 20 of the // PRIVATEKEYBLOB structure. //------------------------------------- byte[] test=new byte[1024]; Marshal.Copy((IntPtr)(pPrivateKeyBlob.ToInt32()),test,0,1024); this.PutFileBytes(@"c:\testkeyPrivate.txt",test,test.Length ); byte[] Exponent = new byte[64]; Marshal.Copy((IntPtr)(pPrivateKeyBlob.ToInt32()), Exponent, 4, 64); Array.Reverse(Exponent); // Reverse the byte order. // Get the length of the modulus. // To do this extract the bit length of the modulus // from the PRIVATEBLOB. The bit length of the modulus is at bytes // 13 through 17 of the PRIVATEBLOB. int BitLength = Marshal.ReadInt32(pPrivateKeyBlob, 16); // Get the modulus. The modulus starts at the 21st byte of the // PRIVATEBLOB structure and is BitLengh/8 bytes in length. byte[] Modulus = new byte[BitLength / 8]; //byte[] Modulus = new byte[BitLength / 16]; Marshal.Copy((IntPtr)(pPrivateKeyBlob.ToInt32() + 20), Modulus, 0, BitLength / 8); Array.Reverse(Modulus); // Reverse the byte order. // Performs asymmetric encryption and decryption using the implementation of the // RSA algorithm provided by the cryptographic service provider (CSP) RSACryptoServiceProvider rsacsp = null; // Put the modulus and exponent into an RSAParameters object. RSAParameters rsaparms = new RSAParameters(); rsaparms.Exponent = Exponent; rsaparms.Modulus = Modulus; // Import the modulus and exponent into an RSACryptoServiceProvider // object via the RSAParameters object. rsacsp = new RSACryptoServiceProvider(512,GetCSPParams()); rsacsp.ImportParameters(rsaparms); decBuffer=rsacsp.Decrypt(rawBuffer,false); Cleanup: if (pDesiredCert != IntPtr.Zero) EncryptDecrypt.Wincrypt.CertFreeCertificateContext(pDesiredCert); if (hProv != IntPtr.Zero) EncryptDecrypt.Wincrypt.CryptReleaseContext(hProv, 0); if (pPrivateKeyBlob != IntPtr.Zero) Marshal.FreeHGlobal(pPrivateKeyBlob); return decBuffer; } public byte[] GetFileBytes(String filename) { if(!File.Exists(filename)) return null; Stream stream=new FileStream(filename,FileMode.Open); int datalen = (int)stream.Length; byte[] filebytes =new byte[datalen]; stream.Seek(0,SeekOrigin.Begin); stream.Read(filebytes,0,datalen); stream.Close(); return filebytes; } public void PutFileBytes(String outfile, byte[] data, int bytes) { FileStream fs = null; if(bytes > data.Length) { Console.WriteLine("Too many bytes"); return; } try { fs = new FileStream(outfile, FileMode.Create); fs.Write(data, 0, bytes); Console.WriteLine("Wrote file '{0}'", outfile) ; } catch(Exception e) { Console.WriteLine(e.Message) ; } finally { fs.Close(); } } private void button1_Click(object sender, System.EventArgs e) { byte[] rawBuffer=GetFileBytes(@"c:\rajesh.txt"); byte[] encBuffer= Encrypt(rawBuffer,true); PutFileBytes(@"c:\rajeshout.txt",encBuffer,encBuffer.Length); } private void button2_Click(object sender, System.EventArgs e) { byte[] rawBuffer=GetFileBytes(@"c:\rajeshout.txt"); byte[] decBuffer= Decrypt(rawBuffer); PutFileBytes(@"c:\rajeshdec.txt",decBuffer,decBuffer.Length); } public static CspParameters GetCSPParams() { CspParameters cspParams = new CspParameters(1); cspParams.KeyContainerName = "slcchander512"; cspParams.KeyNumber=2; cspParams.ProviderType = 1; cspParams.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0"; //cspParams.Flags=CspProviderFlags.UseMachineKeyStore; return cspParams; } } -- Rajesh Thareja In fact, for a cryptosystem to be secure it must be probabilistic and it
must be impossible to correlate cipher text to a plain text for an adversary that doesn't have access to secret decryption key. period. Any deterministic cryptosystem is insecure (i.e. any deterministic cryptosystem fails to satisfy definition of semantic security which is equivalent to IND-CPA for public key cryptosystems). period. -Valery. http://www.harper.no/valery P.S. you may check my blog for brief explanation of what I wrote above. Show quoteHide quote "Rajesh" <Raj***@discussions.microsoft.com> wrote in message news:310C5F99-0533-4BDE-AF3B-9EFEDF882801@microsoft.com... > Hi I Have following program. > > When I run this program and try to encrypt the file using the "Encrypt" > button, the file gets encrypted. But every time i do encrypt, I get a > different output. > > As per my knowledge of the cryptography, every time I encrypt same data > using the same key, I should get the same output. I want to use the key > imported into my local store (in this case the store name is ""). > > Any help is appreciated. > > Thanks > > //------------------------------------------------------------------------------------------- > using System; > using System.IO; > using System.Reflection; > using System.Text; > using System.Collections; > using System.ComponentModel; > using System.Windows.Forms; > using System.Data; > using System.Drawing; > using System.Security.Cryptography.X509Certificates; > using System.Runtime.InteropServices; > using System.Security.Cryptography; > > namespace EncryptDecrypt > { > } > public sealed class CERTPROPS_INFO > { > public CERTPROPS_INFO(byte[] hash, string certsubjname) > { > this.sha1hash = hash; > this.SubjectNameCN = certsubjname; > } > public byte[] Hash > { > get > { > return sha1hash; > } > } > public String Name > { > get > { > return SubjectNameCN; > } > } > > private byte[] sha1hash; > private String SubjectNameCN; > } > > > public class Form1 : System.Windows.Forms.Form > { > private System.Windows.Forms.Button button1; > private System.Windows.Forms.Button button2; > > private System.ComponentModel.Container components = null; > > public Form1() > { > InitializeComponent(); > } > > protected override void Dispose( bool disposing ) > { > if( disposing ) > { > if (components != null) > { > components.Dispose(); > } > } > base.Dispose( disposing ); > } > > > #region Windows Form Designer generated code > private void InitializeComponent() > { > this.button1 = new System.Windows.Forms.Button(); > this.button2 = new System.Windows.Forms.Button(); > this.SuspendLayout(); > // button1 > this.button1.Location = new System.Drawing.Point(72, 40); > this.button1.Name = "button1"; > this.button1.Size = new System.Drawing.Size(128, 48); > this.button1.TabIndex = 0; > this.button1.Text = "Encrypt"; > this.button1.Click += new System.EventHandler(this.button1_Click); > // button2 > this.button2.Location = new System.Drawing.Point(72, 120); > this.button2.Name = "button2"; > this.button2.Size = new System.Drawing.Size(128, 40); > this.button2.TabIndex = 1; > this.button2.Text = "Decrypt"; > this.button2.Click += new System.EventHandler(this.button2_Click); > // Form1 > this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); > this.ClientSize = new System.Drawing.Size(292, 266); > this.Controls.AddRange(new System.Windows.Forms.Control[] { > this.button2, > this.button1}); > this.Name = "Form1"; > this.Text = "Form1"; > this.ResumeLayout(false); > } > #endregion > > /// The main entry point for the application. > [STAThread] > static void Main() > { > > Application.Run(new Form1()); > } > > > public byte[] Encrypt(byte[] data) > { > byte[] rawBuffer=data; > byte[] encBuffer=null; > > // Length of the string to be encrypted > uint bufLength= (uint)rawBuffer.Length; > > // Initialize the handle to Public key BLOB. > IntPtr pPublicKeyBlob = IntPtr.Zero; > > // Handle to the certificate store (MyStore) > IntPtr hSysStore; > > // Open the system store > hSysStore = EncryptDecrypt.Wincrypt.CertOpenSystemStore(IntPtr.Zero, > EncryptDecrypt.Wincrypt.MyStore) ; // MyStore > > // Handle to the certificate > IntPtr pDesiredCert=IntPtr.Zero; > > // Finding the certificate in store for the using subject string > "administrator" > // This function returns handle to the certificate > pDesiredCert = > EncryptDecrypt.Wincrypt.CertFindCertificateInStore(hSysStore, > EncryptDecrypt.Wincrypt.X509_ASN_ENCODING, 0, > EncryptDecrypt.Wincrypt.CERT_FIND_SUBJECT_STR, "administrator", > pDesiredCert); //administrator > > if(pDesiredCert!=IntPtr.Zero) > { > Console.WriteLine("The desired certificate was found. \n"); > } > else > { > Console.WriteLine("Could not find the desired certificate.\n"); > } > > // Handle to particular key container within CSP > IntPtr hProv = IntPtr.Zero; > // The CryptAcquireContext function is used to acquire a handle to > // a particular key container within a particular cryptographic > // service provider (CSP). > // 'slcchander512' is the name of the container which contains the key > // pairs for the requested certificate.[Specified while requesting for > // administrator] > > if (!EncryptDecrypt.Wincrypt.CryptAcquireContext( > ref hProv, // Handle to be acquired > "slcchander512", // Key Container's name > null, // Name of the CSP -----default is null > ----EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > EncryptDecrypt.Wincrypt.PROV_RSA_FULL, //Specifies the type of provider > to acquire. The PROV_RSA_FULL provider type supports both digital > signatures > and data encryption > 0 > )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT > { > Console.Write("CryptAcquireContext failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > // The CryptSetProvParam function customizes the operations of a > cryptographic > // service provider (CSP). This function is commonly used to set a > security > // descriptor on the key container associated with a CSP to control access > to > // the private keys in that key container. > > if(!EncryptDecrypt.Wincrypt.CryptSetProvParam( > hProv, > EncryptDecrypt.Wincrypt.PP_CLIENT_HWND, > EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > 0)) > { > Console.WriteLine(Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > // To acquire context again with Provider's name > if (EncryptDecrypt.Wincrypt.CryptAcquireContext( > ref hProv, > "slcchander512", > EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > EncryptDecrypt.Wincrypt.PROV_RSA_FULL, > 0 > )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT > { > Console.Write("CryptAcquireContext failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > // Import the public key information from the certificate context > // into a key container by passing the pointer to the > // SubjectPublicKeyInfo member of the CERT_INFO structure > // into CryptImportPublicKeyInfoEx. > > // An Additional byte offset, Adding to the pointer before read > IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(pDesiredCert, 12); > > // For public key subject pointer, adding the integer number to the > // certificate handle > IntPtr pSubjectPublicKeyInfo = (IntPtr)(pDesiredCert.ToInt32() + 56); > > // Handle to the public key > IntPtr hKey=IntPtr.Zero; > > // Getting the handle of one of a user's two public/private key pairs. > if(!EncryptDecrypt.Wincrypt.CryptGetUserKey( > hProv, > EncryptDecrypt.Wincrypt.AT_KEYEXCHANGE, > ref hKey)) > { > Console.Write("CryptGetUserKey failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > // Now that the key is imported into a key container. > // CryptExportKey is used to export the public key to the PUBLICKEYBLOB > // format. > > // Gets the size of the buffer needed to hold the PUBLICKEYBLOB structure. > // Length for public key > uint dwDataLen = 0; > > //Handle to the Exported key (public key) > IntPtr hExpkey= IntPtr.Zero; > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hKey, > hExpkey, > EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, > 0, > pPublicKeyBlob, > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " > + Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > pPublicKeyBlob = Marshal.AllocHGlobal((int)dwDataLen); > > // Then export the public key into the PUBLICKEYBLOB format by passing > length. > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hKey, > hExpkey, > EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, > 0, > pPublicKeyBlob, > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " > + Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > // Get the public exponent. > // The public exponent is located in bytes 17 through 20 of the > // PUBLICKEYBLOB structure. > byte[] Exponent = new byte[4]; > > // A 32-bit signed integer equal to the value of this instance > Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 16), Exponent, 0, 4); > > // Reverse the byte order. > Array.Reverse(Exponent); > > // Get the length of the modulus. > // To do this extract the bit length of the modulus from the > PUBLICKEYBLOB. > // The bit length of the modulus is at bytes 13 through 17 of the > PUBLICKEYBLOB. > int BitLength = Marshal.ReadInt32(pPublicKeyBlob, 12); > > // Get the modulus. The modulus starts at the 21st byte of the > // PUBLICKEYBLOB structure and is BitLengh/8 bytes in length. > // byte[] Modulus = new byte[BitLength / 8]; > > byte[] Modulus = new byte[BitLength / 8]; > > Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 20), Modulus, > 0,BitLength / 8); > //stop now Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 4), Modulus, > 0,BitLength / 8); > > Array.Reverse(Modulus); // Reverse the byte order. > > // Performs asymmetric encryption and decryption using the implementation > of the > // RSA algorithm provided by the cryptographic service provider (CSP) > > > // Put the modulus and exponent into an RSAParameters object. > RSAParameters rsaparms = new RSAParameters(); > rsaparms.Exponent = Exponent; > rsaparms.Modulus = Modulus; > > // Import the modulus and exponent into an RSACryptoServiceProvider > // object via the RSAParameters object. > RSACryptoServiceProvider rsacsp = null; > rsacsp = new RSACryptoServiceProvider(512,GetCSPParams()); > rsacsp.ImportParameters(rsaparms); > encBuffer=rsacsp.Encrypt(rawBuffer,false); > > Cleanup: > > if (pDesiredCert != IntPtr.Zero) > EncryptDecrypt.Wincrypt.CertFreeCertificateContext(pDesiredCert); > > if (hProv != IntPtr.Zero) > EncryptDecrypt.Wincrypt.CryptReleaseContext(hProv, 0); > > if (pPublicKeyBlob != IntPtr.Zero) > Marshal.FreeHGlobal(pPublicKeyBlob); > return encBuffer; > } > > enum CheckTrue > { > first, > second > } > public byte[] Encrypt(byte[] data,bool bchk) > { > // byte array of plain text to be encrypted > byte[] rawBuffer=data; > // byte array of encrypted text will be generated in this array > byte[] encBuffer=null; > > // Length of the string to be encrypted > uint bufLength= (uint)rawBuffer.Length; > > // Initialize the handle to Public key BLOB. > IntPtr pPublicKeyBlob = IntPtr.Zero; > > // Handle to the certificate store (MyStore) > IntPtr hSysStore; > > // Open the system store > hSysStore = EncryptDecrypt.Wincrypt.CertOpenSystemStore(IntPtr.Zero, > EncryptDecrypt.Wincrypt.MyStore) ; // MyStore > > // Handle to the certificate > IntPtr pDesiredCert=IntPtr.Zero; > > // Finding the certificate in store for the using subject string > "administrator" > // This function returns handle to the certificate > pDesiredCert = > EncryptDecrypt.Wincrypt.CertFindCertificateInStore(hSysStore, > EncryptDecrypt.Wincrypt.X509_ASN_ENCODING, 0, > EncryptDecrypt.Wincrypt.CERT_FIND_SUBJECT_STR, "administrator", > pDesiredCert); //administrator > > if(pDesiredCert!=IntPtr.Zero) > { > Console.WriteLine("The desired certificate was found. \n"); > } > else > { > Console.WriteLine("Could not find the desired certificate.\n"); > } > > // Handle to particular key container within CSP > IntPtr hProv = IntPtr.Zero; > > // The CryptAcquireContext function is used to acquire a handle to > // a particular key container within a particular cryptographic > // service provider (CSP). > // 'slcchander512' is the name of the container which contains the key > // pairs for the requested certificate.[Specified while requesting for > // administrator] > > if (!EncryptDecrypt.Wincrypt.CryptAcquireContext( > ref hProv, // Handle to be acquired > "slcchander512", // Key Container's name > null, // Name of the CSP -----default is null > ----EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > EncryptDecrypt.Wincrypt.PROV_RSA_FULL, //Specifies the type of provider > to acquire. The PROV_RSA_FULL provider type supports both digital > signatures > and data encryption > 0 > )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT > { > Console.Write("CryptAcquireContext failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > // The CryptSetProvParam function customizes the operations of a > cryptographic > // service provider (CSP). This function is commonly used to set a > security > // descriptor on the key container associated with a CSP to control access > to > // the private keys in that key container. > > if(!EncryptDecrypt.Wincrypt.CryptSetProvParam( > hProv, > EncryptDecrypt.Wincrypt.PP_CLIENT_HWND, > EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > 0)) > { > Console.WriteLine(Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > // To acquire context again with Provider's name > if (EncryptDecrypt.Wincrypt.CryptAcquireContext( > ref hProv, > "slcchander512", > EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > EncryptDecrypt.Wincrypt.PROV_RSA_FULL, > 0 > )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT > { > Console.Write("CryptAcquireContext failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > // Import the public key information from the certificate context > // into a key container by passing the pointer to the > // SubjectPublicKeyInfo member of the CERT_INFO structure > // into CryptImportPublicKeyInfoEx. > > // An Additional byte offset, Adding to the pointer before read > IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(pDesiredCert, 12); > > // For public key subject pointer, adding the integer number to the > // certificate handle > IntPtr pSubjectPublicKeyInfo = (IntPtr)(pDesiredCert.ToInt32() + 56); > > // Handle to the public key > IntPtr hKey=IntPtr.Zero; > > // Getting the handle of one of a user's two public/private key pairs. > if(!EncryptDecrypt.Wincrypt.CryptGetUserKey( > hProv, > EncryptDecrypt.Wincrypt.AT_KEYEXCHANGE, > ref hKey)) > { > Console.Write("CryptGetUserKey failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > > // The CryptImportPublicKeyInfoEx function imports public key > // information into the CSP and returns a handle of the public key. > // Now that the key is imported into a key container. > // CryptExportKey is used to export the public key to the PUBLICKEYBLOB > // format. > > // Gets the size of the buffer needed to hold the PUBLICKEYBLOB structure. > // Length for public key > uint dwDataLen = 0; > > //Handle to the Exported key (public key) > IntPtr hExpkey= IntPtr.Zero; > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hKey, > hExpkey, > EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, > 0, > pPublicKeyBlob, > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " > + Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > pPublicKeyBlob = Marshal.AllocHGlobal((int)dwDataLen); > > // Then export the public key into the PUBLICKEYBLOB format by passing > length. > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hKey, > hExpkey, > EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, > 0, > pPublicKeyBlob, > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " > + Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > // Get the public exponent. > // The public exponent is located in bytes 17 through 20 of the > // PUBLICKEYBLOB structure. > byte[] Exponent = new byte[4]; > > // A 32-bit signed integer equal to the value of this instance > //stop now Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 164), > Exponent, 0, 4); > Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 16), Exponent, 0, 4); > > // Reverse the byte order. > Array.Reverse(Exponent); > > // Get the length of the modulus. > // To do this extract the bit length of the modulus from the > PUBLICKEYBLOB. > // The bit length of the modulus is at bytes 13 through 17 of the > PUBLICKEYBLOB. > int BitLength = Marshal.ReadInt32(pPublicKeyBlob, 12); > //stop now int BitLength = 64 * 8; > > // Get the modulus. The modulus starts at the 21st byte of the > // PUBLICKEYBLOB structure and is BitLengh/8 bytes in length. > // byte[] Modulus = new byte[BitLength / 8]; > > byte[] Modulus = new byte[BitLength / 8]; > > Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 20), Modulus, 0,BitLength > / 8); > > Array.Reverse(Modulus); // Reverse the byte order. > > // Performs asymmetric encryption and decryption using the implementation > of the > // RSA algorithm provided by the cryptographic service provider (CSP) > > > // Put the modulus and exponent into an RSAParameters object. > > RSAParameters rsaparms = new RSAParameters(); > rsaparms.Exponent = Exponent; > rsaparms.Modulus = Modulus; > > // Import the modulus and exponent into an RSACryptoServiceProvider > // object via the RSAParameters object. > RSACryptoServiceProvider rsacsp = null; > rsacsp = new RSACryptoServiceProvider(512,GetCSPParams()); > rsacsp.ImportParameters(rsaparms); > encBuffer=rsacsp.Encrypt(rawBuffer,false); > > Cleanup: > > if (pDesiredCert != IntPtr.Zero) > EncryptDecrypt.Wincrypt.CertFreeCertificateContext(pDesiredCert); > > if (hProv != IntPtr.Zero) > EncryptDecrypt.Wincrypt.CryptReleaseContext(hProv, 0); > > if (pPublicKeyBlob != IntPtr.Zero) > Marshal.FreeHGlobal(pPublicKeyBlob); > return encBuffer; > } > > // This function takes a encrypted byte array and returns decrypted data > public byte[] Decrypt(byte[] data) > { > //Byte array containing encrypted data > byte[] rawBuffer=data; > //Byte array for containing decrypted data > byte[] decBuffer=null; > > //handle to the key container within CSP provider > IntPtr hProv = IntPtr.Zero; > > IntPtr hExpkey = IntPtr.Zero; > > //Length of the data to be encrypted > uint dataLength = (uint)data.Length; > > //Handle to the private key blob > IntPtr pPrivateKeyBlob = IntPtr.Zero; > > > //Handle to the private key > IntPtr hPrivateKey=IntPtr.Zero; > > //Handle to the Certificate key > IntPtr hSysStore; > > //Opening certificate store > hSysStore = EncryptDecrypt.Wincrypt.CertOpenSystemStore(IntPtr.Zero, > EncryptDecrypt.Wincrypt.MyStore) ; // MyStore > > //Handle to the certificate thru which private key is to be retrieved > IntPtr pDesiredCert=IntPtr.Zero; > > //Retrieves the certificate handle > pDesiredCert = > EncryptDecrypt.Wincrypt.CertFindCertificateInStore(hSysStore, > EncryptDecrypt.Wincrypt.X509_ASN_ENCODING, 0, > EncryptDecrypt.Wincrypt.CERT_FIND_SUBJECT_STR, "administrator", > pDesiredCert); //administrator > > if(pDesiredCert!=IntPtr.Zero) > { > Console.WriteLine("The desired certificate was found. \n"); > } > else > { > Console.WriteLine("Could not find the desired certificate.\n"); > } > // The CryptAcquireContext function is used to acquire a handle to > // a particular key container within a particular cryptographic > // service provider (CSP). > // 'slcchander512' is the name of the container which contains the key > // pairs for the requested certificate.[Specified while requesting for > // administrator] > > if (!EncryptDecrypt.Wincrypt.CryptAcquireContext( > ref hProv, > "slcchander512", > null, > EncryptDecrypt.Wincrypt.PROV_RSA_FULL, > 0 > )) > { > Console.Write("CryptAcquireContext failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > //Retrieves a handle of one of a user's two public/private key pairs. > if (!EncryptDecrypt.Wincrypt.CryptGetUserKey( > hProv, > EncryptDecrypt.Wincrypt.AT_KEYEXCHANGE, > ref hPrivateKey)) > { > Console.Write("CryptGetUserKey failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > //Holds length of the private key blob > uint dwDataLen = 0; > > //The CryptExportKey function exports a cryptographic key or a key pair > // from a cryptographic service provider (CSP) in a secure manner. > //Get the length of BLOB first time > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hPrivateKey, > hExpkey, > EncryptDecrypt.Wincrypt.PRIVATEKEYBLOB, > 0, > IntPtr.Zero , > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > // Then export the private key into the PRIVATEKEYBLOB format. > pPrivateKeyBlob = Marshal.AllocHGlobal((int)dwDataLen); > > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hPrivateKey, > hExpkey, > EncryptDecrypt.Wincrypt.PRIVATEKEYBLOB, > 0, > pPrivateKeyBlob, > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > // Get the public exponent. > // The private exponent is located in bytes 17 through 20 of the > // PRIVATEKEYBLOB structure. > //------------------------------------- > byte[] test=new byte[1024]; > > Marshal.Copy((IntPtr)(pPrivateKeyBlob.ToInt32()),test,0,1024); > this.PutFileBytes(@"c:\testkeyPrivate.txt",test,test.Length ); > > byte[] Exponent = new byte[64]; > Marshal.Copy((IntPtr)(pPrivateKeyBlob.ToInt32()), Exponent, 4, 64); > Array.Reverse(Exponent); // Reverse the byte order. > > // Get the length of the modulus. > // To do this extract the bit length of the modulus > // from the PRIVATEBLOB. The bit length of the modulus is at bytes > // 13 through 17 of the PRIVATEBLOB. > int BitLength = Marshal.ReadInt32(pPrivateKeyBlob, 16); > > // Get the modulus. The modulus starts at the 21st byte of the > // PRIVATEBLOB structure and is BitLengh/8 bytes in length. > byte[] Modulus = new byte[BitLength / 8]; > > //byte[] Modulus = new byte[BitLength / 16]; > > Marshal.Copy((IntPtr)(pPrivateKeyBlob.ToInt32() + 20), Modulus, 0, > BitLength / 8); > Array.Reverse(Modulus); // Reverse the byte order. > > // Performs asymmetric encryption and decryption using the implementation > of the > // RSA algorithm provided by the cryptographic service provider (CSP) > RSACryptoServiceProvider rsacsp = null; > > // Put the modulus and exponent into an RSAParameters object. > RSAParameters rsaparms = new RSAParameters(); > rsaparms.Exponent = Exponent; > rsaparms.Modulus = Modulus; > > // Import the modulus and exponent into an RSACryptoServiceProvider > // object via the RSAParameters object. > rsacsp = new RSACryptoServiceProvider(512,GetCSPParams()); > rsacsp.ImportParameters(rsaparms); > decBuffer=rsacsp.Decrypt(rawBuffer,false); > > Cleanup: > > if (pDesiredCert != IntPtr.Zero) > EncryptDecrypt.Wincrypt.CertFreeCertificateContext(pDesiredCert); > > if (hProv != IntPtr.Zero) > EncryptDecrypt.Wincrypt.CryptReleaseContext(hProv, 0); > > if (pPrivateKeyBlob != IntPtr.Zero) > Marshal.FreeHGlobal(pPrivateKeyBlob); > > return decBuffer; > } > > > public byte[] GetFileBytes(String filename) > { > if(!File.Exists(filename)) > return null; > Stream stream=new FileStream(filename,FileMode.Open); > int datalen = (int)stream.Length; > byte[] filebytes =new byte[datalen]; > stream.Seek(0,SeekOrigin.Begin); > stream.Read(filebytes,0,datalen); > stream.Close(); > return filebytes; > } > > public void PutFileBytes(String outfile, byte[] data, int bytes) > { > FileStream fs = null; > if(bytes > data.Length) > { > Console.WriteLine("Too many bytes"); > return; > } > try > { > fs = new FileStream(outfile, FileMode.Create); > fs.Write(data, 0, bytes); > Console.WriteLine("Wrote file '{0}'", outfile) ; > } > catch(Exception e) > { > Console.WriteLine(e.Message) ; > } > finally > { > fs.Close(); > } > } > > > private void button1_Click(object sender, System.EventArgs e) > { > byte[] rawBuffer=GetFileBytes(@"c:\rajesh.txt"); > byte[] encBuffer= Encrypt(rawBuffer,true); > PutFileBytes(@"c:\rajeshout.txt",encBuffer,encBuffer.Length); > } > > private void button2_Click(object sender, System.EventArgs e) > { > byte[] rawBuffer=GetFileBytes(@"c:\rajeshout.txt"); > byte[] decBuffer= Decrypt(rawBuffer); > PutFileBytes(@"c:\rajeshdec.txt",decBuffer,decBuffer.Length); > > } > > public static CspParameters GetCSPParams() > { > CspParameters cspParams = new CspParameters(1); > > cspParams.KeyContainerName = "slcchander512"; > cspParams.KeyNumber=2; > cspParams.ProviderType = 1; > > cspParams.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0"; > //cspParams.Flags=CspProviderFlags.UseMachineKeyStore; > > return cspParams; > } > > } > > > -- > Rajesh Thareja Rajesh
Right now what you are trying to do is you are exporting the public key into the PUBLICKEYBLOB format. After that you are extracting exponent and modulus from it by specifying the bit length of the modulus at bytes 13 through 17 of the PUBLICKEYBLOB. The bit length varies according to the key size i.e. 512, 1024 etc. So check the CSP specific documentation containing correct bit length of exponent and modulus. I think you are not entering correct bit length and position. Show quoteHide quote "Rajesh" wrote: > Hi I Have following program. > > When I run this program and try to encrypt the file using the "Encrypt" > button, the file gets encrypted. But every time i do encrypt, I get a > different output. > > As per my knowledge of the cryptography, every time I encrypt same data > using the same key, I should get the same output. I want to use the key > imported into my local store (in this case the store name is ""). > > Any help is appreciated. > > Thanks > > //------------------------------------------------------------------------------------------- > using System; > using System.IO; > using System.Reflection; > using System.Text; > using System.Collections; > using System.ComponentModel; > using System.Windows.Forms; > using System.Data; > using System.Drawing; > using System.Security.Cryptography.X509Certificates; > using System.Runtime.InteropServices; > using System.Security.Cryptography; > > namespace EncryptDecrypt > { > } > public sealed class CERTPROPS_INFO > { > public CERTPROPS_INFO(byte[] hash, string certsubjname) > { > this.sha1hash = hash; > this.SubjectNameCN = certsubjname; > } > public byte[] Hash > { > get > { > return sha1hash; > } > } > public String Name > { > get > { > return SubjectNameCN; > } > } > > private byte[] sha1hash; > private String SubjectNameCN; > } > > > public class Form1 : System.Windows.Forms.Form > { > private System.Windows.Forms.Button button1; > private System.Windows.Forms.Button button2; > > private System.ComponentModel.Container components = null; > > public Form1() > { > InitializeComponent(); > } > > protected override void Dispose( bool disposing ) > { > if( disposing ) > { > if (components != null) > { > components.Dispose(); > } > } > base.Dispose( disposing ); > } > > > #region Windows Form Designer generated code > private void InitializeComponent() > { > this.button1 = new System.Windows.Forms.Button(); > this.button2 = new System.Windows.Forms.Button(); > this.SuspendLayout(); > // button1 > this.button1.Location = new System.Drawing.Point(72, 40); > this.button1.Name = "button1"; > this.button1.Size = new System.Drawing.Size(128, 48); > this.button1.TabIndex = 0; > this.button1.Text = "Encrypt"; > this.button1.Click += new System.EventHandler(this.button1_Click); > // button2 > this.button2.Location = new System.Drawing.Point(72, 120); > this.button2.Name = "button2"; > this.button2.Size = new System.Drawing.Size(128, 40); > this.button2.TabIndex = 1; > this.button2.Text = "Decrypt"; > this.button2.Click += new System.EventHandler(this.button2_Click); > // Form1 > this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); > this.ClientSize = new System.Drawing.Size(292, 266); > this.Controls.AddRange(new System.Windows.Forms.Control[] { > this.button2, > this.button1}); > this.Name = "Form1"; > this.Text = "Form1"; > this.ResumeLayout(false); > } > #endregion > > /// The main entry point for the application. > [STAThread] > static void Main() > { > > Application.Run(new Form1()); > } > > > public byte[] Encrypt(byte[] data) > { > byte[] rawBuffer=data; > byte[] encBuffer=null; > > // Length of the string to be encrypted > uint bufLength= (uint)rawBuffer.Length; > > // Initialize the handle to Public key BLOB. > IntPtr pPublicKeyBlob = IntPtr.Zero; > > // Handle to the certificate store (MyStore) > IntPtr hSysStore; > > // Open the system store > hSysStore = EncryptDecrypt.Wincrypt.CertOpenSystemStore(IntPtr.Zero, > EncryptDecrypt.Wincrypt.MyStore) ; // MyStore > > // Handle to the certificate > IntPtr pDesiredCert=IntPtr.Zero; > > // Finding the certificate in store for the using subject string > "administrator" > // This function returns handle to the certificate > pDesiredCert = > EncryptDecrypt.Wincrypt.CertFindCertificateInStore(hSysStore, > EncryptDecrypt.Wincrypt.X509_ASN_ENCODING, 0, > EncryptDecrypt.Wincrypt.CERT_FIND_SUBJECT_STR, "administrator", > pDesiredCert); //administrator > > if(pDesiredCert!=IntPtr.Zero) > { > Console.WriteLine("The desired certificate was found. \n"); > } > else > { > Console.WriteLine("Could not find the desired certificate.\n"); > } > > // Handle to particular key container within CSP > IntPtr hProv = IntPtr.Zero; > // The CryptAcquireContext function is used to acquire a handle to > // a particular key container within a particular cryptographic > // service provider (CSP). > // 'slcchander512' is the name of the container which contains the key > // pairs for the requested certificate.[Specified while requesting for > // administrator] > > if (!EncryptDecrypt.Wincrypt.CryptAcquireContext( > ref hProv, // Handle to be acquired > "slcchander512", // Key Container's name > null, // Name of the CSP -----default is null > ----EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > EncryptDecrypt.Wincrypt.PROV_RSA_FULL, //Specifies the type of provider > to acquire. The PROV_RSA_FULL provider type supports both digital signatures > and data encryption > 0 > )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT > { > Console.Write("CryptAcquireContext failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > // The CryptSetProvParam function customizes the operations of a > cryptographic > // service provider (CSP). This function is commonly used to set a security > // descriptor on the key container associated with a CSP to control access > to > // the private keys in that key container. > > if(!EncryptDecrypt.Wincrypt.CryptSetProvParam( > hProv, > EncryptDecrypt.Wincrypt.PP_CLIENT_HWND, > EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > 0)) > { > Console.WriteLine(Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > // To acquire context again with Provider's name > if (EncryptDecrypt.Wincrypt.CryptAcquireContext( > ref hProv, > "slcchander512", > EncryptDecrypt.Wincrypt.MS_ENHANCED_PROV, > EncryptDecrypt.Wincrypt.PROV_RSA_FULL, > 0 > )) //EncryptDecrypt.Wincrypt.CRYPT_VERIFYCONTEXT > { > Console.Write("CryptAcquireContext failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > // Import the public key information from the certificate context > // into a key container by passing the pointer to the > // SubjectPublicKeyInfo member of the CERT_INFO structure > // into CryptImportPublicKeyInfoEx. > > // An Additional byte offset, Adding to the pointer before read > IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(pDesiredCert, 12); > > // For public key subject pointer, adding the integer number to the > // certificate handle > IntPtr pSubjectPublicKeyInfo = (IntPtr)(pDesiredCert.ToInt32() + 56); > > // Handle to the public key > IntPtr hKey=IntPtr.Zero; > > // Getting the handle of one of a user's two public/private key pairs. > if(!EncryptDecrypt.Wincrypt.CryptGetUserKey( > hProv, > EncryptDecrypt.Wincrypt.AT_KEYEXCHANGE, > ref hKey)) > { > Console.Write("CryptGetUserKey failed :" + > Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > // Now that the key is imported into a key container. > // CryptExportKey is used to export the public key to the PUBLICKEYBLOB > // format. > > // Gets the size of the buffer needed to hold the PUBLICKEYBLOB structure. > // Length for public key > uint dwDataLen = 0; > > //Handle to the Exported key (public key) > IntPtr hExpkey= IntPtr.Zero; > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hKey, > hExpkey, > EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, > 0, > pPublicKeyBlob, > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " > + Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > pPublicKeyBlob = Marshal.AllocHGlobal((int)dwDataLen); > > // Then export the public key into the PUBLICKEYBLOB format by passing > length. > if (!EncryptDecrypt.Wincrypt.CryptExportKey( > hKey, > hExpkey, > EncryptDecrypt.Wincrypt.PUBLICKEYBLOB, > 0, > pPublicKeyBlob, > ref dwDataLen)) > { > Console.WriteLine("CryptExportKey failed: " > + Marshal.GetLastWin32Error().ToString()); > goto Cleanup; > } > > > // Get the public exponent. > // The public exponent is located in bytes 17 through 20 of the > // PUBLICKEYBLOB structure. > byte[] Exponent = new byte[4]; > > // A 32-bit signed integer equal to the value of this instance > Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 16), Exponent, 0, 4); > > // Reverse the byte order. > Array.Reverse(Exponent); > > // Get the length of the modulus. > // To do this extract the bit length of the modulus from the > PUBLICKEYBLOB. > // The bit length of the modulus is at bytes 13 through 17 of the > PUBLICKEYBLOB.
encrypting app.config with RSA
Application Security and Trust Mail merge with an MD5 hash. Kerberos S4U problem Directory access check SHA1Managed class has different results in 2.0 vs. 1.1?? LogParser - Error security issue with with windows service account Which Certificate store does IIS look at use CAS demand or not? |
|||||||||||||||||||||||