Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
platform
active.directory
adsi
adsi.iis-admin
base
com_ole
complus_mts
component_svcs
database
directx
gdi
graphics_mm
internet.client
internet.server
internet.server.isapi-dev
localization
mapi
messaging
msi
mslayerforunicode
multimedia
networking
networking.ipv6
sdk_install
security
shell
telephony.tapi_2
telephony.tapi_3
telephony.tsp
telephony.wte
tools
ui
ui_shell
win_base_svcs
win16
  
 
date: Thu, 22 May 2008 06:57:13 -0700,    group: microsoft.public.platformsdk.security        back       


CryptDecrypt with error 0x80090005   
I wrongly posted this question in another group.

I have a simple C# program to encrypt and decrypt a small file using a 
smartcard. I can encrypt the file but when I try to decrypit, the 
CryptDecrypt call returns with error code 80090005. The troubled part of the 
program is below 

Can anybody help me ?

private void btnGerarChaveTDES_Click(object sender, EventArgs e)

 {

            IntPtr hProv = new IntPtr();

            string pszContainer = null;

            string pszProvider = "SafeSign Standard Cryptographic Service 
Provider";

            uint dwProvType = 1; // "1 - PROV_RSA_FULL";

            uint dwFlags = 32;   // "8 - CRYPT_NEWKEYSET";

 

            int erro = 0;

 

            CryptAcquireContext(ref hProv, pszContainer, pszProvider, 
dwProvType, dwFlags);

 

            erro = Marshal.GetLastWin32Error();

 

            // Gera a chave TDES

            // =============================================================

            //IntPtr pnKey = new IntPtr();

            IntPtr pnKey = new IntPtr();

            uint Aldid = ((3 << 13) | (3 << 9) | (3));

            uint dwFlags2 = 1;  //1 - CRYPT EXPORTABLE

 

            CryptGenKey(hProv, Aldid, dwFlags2, ref pnKey);

 

            erro = Marshal.GetLastWin32Error();

 

 

 

            // Importa a chava para o cartão

            // =============================================================

            IntPtr hExpKey = new IntPtr();

            IntPtr nPubKey = new IntPtr();

            uint dwFlags3 = 0;

 

            CryptImportKey(hProv, pbData, pbData.Length, nPubKey, dwFlags3, 
ref hExpKey);

 

            erro = Marshal.GetLastWin32Error();

 

 

            // Exporta a chave

            // =============================================================

            Int32 dwBlobType = 1;   //"1 - SIMPLEBLOB";

            Int32 dwFlags4 = 0;

            Byte[] pbData2 = null;

            Int32 pdwDataLen = 0;

 

            CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, null, ref 
pdwDataLen);

 

            erro = Marshal.GetLastWin32Error();

 

            pbData2 = new byte[pdwDataLen];

 

            CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, pbData2, 
ref pdwDataLen);

 

            erro = Marshal.GetLastWin32Error();

 

            GravarArquivo(pbData2, "c:\\BlobTDes.blb");

 

 

            // Ler arquivo texto e encriptar

            // =============================================================

            IntPtr hHash = new IntPtr(0);

            int Final = 1;  // ultimo bloco ou não

            uint dwFlags5 = 0;

 

 

            //byte[] bufferArquivo = new byte[11027 + 130];

            byte[] bufferArquivo = new byte[128];

            byte[] arquivo = LerArquivo("c:\\texto.txt");

            int arquivoLen = arquivo.Length;

 

            arquivo.CopyTo(bufferArquivo, 0);

 

            int dwBufLen = bufferArquivo.Length;

 

 

            CryptEncrypt(pnKey, hHash, Final, dwFlags5, bufferArquivo, ref 
arquivoLen, dwBufLen);

 

            erro = Marshal.GetLastWin32Error();

 

            //byte[] aux = new byte[arquivoLen];

            //for (int i = 0; i < aux.Length; i++)

            //    aux[i] = bufferArquivo[i];

 

            ////GravarArquivo(bufferArquivo, "c:\\texto_cripto.txt");

            //GravarArquivo(aux, "c:\\texto_cripto.txt");

 

 

            //// Zera o vetor de incializaçao

            //// =============================================================

            //uint dwParam = 1;   // 1 - KP_IV

            //byte[] pbData3 = new byte[8];

            //uint dwFlags6 = 0;

 

            //for (int i = 0; i < 8; i++)

            //    pbData3[i] = 0;

 

            //bool bln1 = CryptSetKeyParam(pnKey, dwParam, pbData3, dwFlags6);

 

            //erro = Marshal.GetLastWin32Error();

 

            bool bln2 = CryptDecrypt(pnKey, hHash, Final, dwFlags5, ref 
bufferArquivo, ref arquivoLen);

 

            erro = Marshal.GetLastWin32Error();

 

 

}
date: Thu, 22 May 2008 06:57:13 -0700   author:   Marcio Campos

RE: CryptDecrypt with error 0x80090005   
Hi,

Please try to simplify your code and narrow the use case if you want someone 
to help you. In the posted code, the problem can come from different causes. 
For examples, instead of using an external file (texto.txt), use a hard-coded 
buffer to simplify the problem analyze. Also, check the boolean return value 
of the Crypt function (not only the GetLastError) to be sure which function 
fails. You must also verify the output buffer used in CryptEncrypt is larger 
enough to hold the result (don't forget that there will be paddings).

Cheers,
-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"Marcio Campos" wrote:

> I wrongly posted this question in another group.
> 
> I have a simple C# program to encrypt and decrypt a small file using a 
> smartcard. I can encrypt the file but when I try to decrypit, the 
> CryptDecrypt call returns with error code 80090005. The troubled part of the 
> program is below 
> 
> Can anybody help me ?
> 
> private void btnGerarChaveTDES_Click(object sender, EventArgs e)
> 
>  {
> 
>             IntPtr hProv = new IntPtr();
> 
>             string pszContainer = null;
> 
>             string pszProvider = "SafeSign Standard Cryptographic Service 
> Provider";
> 
>             uint dwProvType = 1; // "1 - PROV_RSA_FULL";
> 
>             uint dwFlags = 32;   // "8 - CRYPT_NEWKEYSET";
> 
>  
> 
>             int erro = 0;
> 
>  
> 
>             CryptAcquireContext(ref hProv, pszContainer, pszProvider, 
> dwProvType, dwFlags);
> 
>  
> 
>             erro = Marshal.GetLastWin32Error();
> 
>  
> 
>             // Gera a chave TDES
> 
>             // =============================================================
> 
>             //IntPtr pnKey = new IntPtr();
> 
>             IntPtr pnKey = new IntPtr();
> 
>             uint Aldid = ((3 << 13) | (3 << 9) | (3));
> 
>             uint dwFlags2 = 1;  //1 - CRYPT EXPORTABLE
> 
>  
> 
>             CryptGenKey(hProv, Aldid, dwFlags2, ref pnKey);
> 
>  
> 
>             erro = Marshal.GetLastWin32Error();
> 
>  
> 
>  
> 
>  
> 
>             // Importa a chava para o cartão
> 
>             // =============================================================
> 
>             IntPtr hExpKey = new IntPtr();
> 
>             IntPtr nPubKey = new IntPtr();
> 
>             uint dwFlags3 = 0;
> 
>  
> 
>             CryptImportKey(hProv, pbData, pbData.Length, nPubKey, dwFlags3, 
> ref hExpKey);
> 
>  
> 
>             erro = Marshal.GetLastWin32Error();
> 
>  
> 
>  
> 
>             // Exporta a chave
> 
>             // =============================================================
> 
>             Int32 dwBlobType = 1;   //"1 - SIMPLEBLOB";
> 
>             Int32 dwFlags4 = 0;
> 
>             Byte[] pbData2 = null;
> 
>             Int32 pdwDataLen = 0;
> 
>  
> 
>             CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, null, ref 
> pdwDataLen);
> 
>  
> 
>             erro = Marshal.GetLastWin32Error();
> 
>  
> 
>             pbData2 = new byte[pdwDataLen];
> 
>  
> 
>             CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, pbData2, 
> ref pdwDataLen);
> 
>  
> 
>             erro = Marshal.GetLastWin32Error();
> 
>  
> 
>             GravarArquivo(pbData2, "c:\\BlobTDes.blb");
> 
>  
> 
>  
> 
>             // Ler arquivo texto e encriptar
> 
>             // =============================================================
> 
>             IntPtr hHash = new IntPtr(0);
> 
>             int Final = 1;  // ultimo bloco ou não
> 
>             uint dwFlags5 = 0;
> 
>  
> 
>  
> 
>             //byte[] bufferArquivo = new byte[11027 + 130];
> 
>             byte[] bufferArquivo = new byte[128];
> 
>             byte[] arquivo = LerArquivo("c:\\texto.txt");
> 
>             int arquivoLen = arquivo.Length;
> 
>  
> 
>             arquivo.CopyTo(bufferArquivo, 0);
> 
>  
> 
>             int dwBufLen = bufferArquivo.Length;
> 
>  
> 
>  
> 
>             CryptEncrypt(pnKey, hHash, Final, dwFlags5, bufferArquivo, ref 
> arquivoLen, dwBufLen);
> 
>  
> 
>             erro = Marshal.GetLastWin32Error();
> 
>  
> 
>             //byte[] aux = new byte[arquivoLen];
> 
>             //for (int i = 0; i < aux.Length; i++)
> 
>             //    aux[i] = bufferArquivo[i];
> 
>  
> 
>             ////GravarArquivo(bufferArquivo, "c:\\texto_cripto.txt");
> 
>             //GravarArquivo(aux, "c:\\texto_cripto.txt");
> 
>  
> 
>  
> 
>             //// Zera o vetor de incializaçao
> 
>             //// =============================================================
> 
>             //uint dwParam = 1;   // 1 - KP_IV
> 
>             //byte[] pbData3 = new byte[8];
> 
>             //uint dwFlags6 = 0;
> 
>  
> 
>             //for (int i = 0; i < 8; i++)
> 
>             //    pbData3[i] = 0;
> 
>  
> 
>             //bool bln1 = CryptSetKeyParam(pnKey, dwParam, pbData3, dwFlags6);
> 
>  
> 
>             //erro = Marshal.GetLastWin32Error();
> 
>  
> 
>             bool bln2 = CryptDecrypt(pnKey, hHash, Final, dwFlags5, ref 
> bufferArquivo, ref arquivoLen);
> 
>  
> 
>             erro = Marshal.GetLastWin32Error();
> 
>  
> 
>  
> 
> }
> 
>  
> 
>  
> 
>
date: Thu, 22 May 2008 07:18:01 -0700   author:   Mounir IDRASSI am

RE: CryptDecrypt with error 0x80090005   
Thanks for you answer.

I can simplify the program according to your suggestion but we did a lot of 
debbuging and:

1) "For examples, instead of using an external file (texto.txt), use a 
hard-coded 
> buffer to simplify the problem analyze. "

The buffer is correct. We tryed alsoo with a hard coded buffer and the 
result is same (fails).

2) "Crypt function (not only the GetLastError) to be sure which function 
> fails. "

The CryptEncrypt functions always fail. We verified with the debbuger. 

3) "You must also verify the output buffer used in CryptEncrypt is larger 
> enough to hold the result (don't forget that there will be paddings)."

The buffer is larger enough to hold the result.

To clarify a little more. All the other crypt functions works fine. The same 
sequence of functions call are done in C++ and works OK.

I wonder if the Key Handler is in some kind of state that makes the function 
CrypDecrypt Fails. See in the code that the Key Handler for Encrypt is the 
same of the Decrypt.

Thanks for your help!

Cheers!!!

"Mounir IDRASSI" wrote:

> Hi,
> 
> Please try to simplify your code and narrow the use case if you want someone 
> to help you. In the posted code, the problem can come from different causes. 
> 

Also, check the boolean return value 
> of the Crypt function (not only the GetLastError) to be sure which function 
> fails. You must also verify the output buffer used in CryptEncrypt is larger 
> enough to hold the result (don't forget that there will be paddings).
> 
> Cheers,
> -- 
> Mounir IDRASSI
> IDRIX
> http://www.idrix.fr
> 
> to reach : mounir_idrix_fr (replace the underscores with the at and dot 
> characters respectively)
> 
> 
> "Marcio Campos" wrote:
> 
> > I wrongly posted this question in another group.
> > 
> > I have a simple C# program to encrypt and decrypt a small file using a 
> > smartcard. I can encrypt the file but when I try to decrypit, the 
> > CryptDecrypt call returns with error code 80090005. The troubled part of the 
> > program is below 
> > 
> > Can anybody help me ?
> > 
> > private void btnGerarChaveTDES_Click(object sender, EventArgs e)
> > 
> >  {
> > 
> >             IntPtr hProv = new IntPtr();
> > 
> >             string pszContainer = null;
> > 
> >             string pszProvider = "SafeSign Standard Cryptographic Service 
> > Provider";
> > 
> >             uint dwProvType = 1; // "1 - PROV_RSA_FULL";
> > 
> >             uint dwFlags = 32;   // "8 - CRYPT_NEWKEYSET";
> > 
> >  
> > 
> >             int erro = 0;
> > 
> >  
> > 
> >             CryptAcquireContext(ref hProv, pszContainer, pszProvider, 
> > dwProvType, dwFlags);
> > 
> >  
> > 
> >             erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >             // Gera a chave TDES
> > 
> >             // =============================================================
> > 
> >             //IntPtr pnKey = new IntPtr();
> > 
> >             IntPtr pnKey = new IntPtr();
> > 
> >             uint Aldid = ((3 << 13) | (3 << 9) | (3));
> > 
> >             uint dwFlags2 = 1;  //1 - CRYPT EXPORTABLE
> > 
> >  
> > 
> >             CryptGenKey(hProv, Aldid, dwFlags2, ref pnKey);
> > 
> >  
> > 
> >             erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >  
> > 
> >  
> > 
> >             // Importa a chava para o cartão
> > 
> >             // =============================================================
> > 
> >             IntPtr hExpKey = new IntPtr();
> > 
> >             IntPtr nPubKey = new IntPtr();
> > 
> >             uint dwFlags3 = 0;
> > 
> >  
> > 
> >             CryptImportKey(hProv, pbData, pbData.Length, nPubKey, dwFlags3, 
> > ref hExpKey);
> > 
> >  
> > 
> >             erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >  
> > 
> >             // Exporta a chave
> > 
> >             // =============================================================
> > 
> >             Int32 dwBlobType = 1;   //"1 - SIMPLEBLOB";
> > 
> >             Int32 dwFlags4 = 0;
> > 
> >             Byte[] pbData2 = null;
> > 
> >             Int32 pdwDataLen = 0;
> > 
> >  
> > 
> >             CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, null, ref 
> > pdwDataLen);
> > 
> >  
> > 
> >             erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >             pbData2 = new byte[pdwDataLen];
> > 
> >  
> > 
> >             CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, pbData2, 
> > ref pdwDataLen);
> > 
> >  
> > 
> >             erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >             GravarArquivo(pbData2, "c:\\BlobTDes.blb");
> > 
> >  
> > 
> >  
> > 
> >             // Ler arquivo texto e encriptar
> > 
> >             // =============================================================
> > 
> >             IntPtr hHash = new IntPtr(0);
> > 
> >             int Final = 1;  // ultimo bloco ou não
> > 
> >             uint dwFlags5 = 0;
> > 
> >  
> > 
> >  
> > 
> >             //byte[] bufferArquivo = new byte[11027 + 130];
> > 
> >             byte[] bufferArquivo = new byte[128];
> > 
> >             byte[] arquivo = LerArquivo("c:\\texto.txt");
> > 
> >             int arquivoLen = arquivo.Length;
> > 
> >  
> > 
> >             arquivo.CopyTo(bufferArquivo, 0);
> > 
> >  
> > 
> >             int dwBufLen = bufferArquivo.Length;
> > 
> >  
> > 
> >  
> > 
> >             CryptEncrypt(pnKey, hHash, Final, dwFlags5, bufferArquivo, ref 
> > arquivoLen, dwBufLen);
> > 
> >  
> > 
> >             erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >             //byte[] aux = new byte[arquivoLen];
> > 
> >             //for (int i = 0; i < aux.Length; i++)
> > 
> >             //    aux[i] = bufferArquivo[i];
> > 
> >  
> > 
> >             ////GravarArquivo(bufferArquivo, "c:\\texto_cripto.txt");
> > 
> >             //GravarArquivo(aux, "c:\\texto_cripto.txt");
> > 
> >  
> > 
> >  
> > 
> >             //// Zera o vetor de incializaçao
> > 
> >             //// =============================================================
> > 
> >             //uint dwParam = 1;   // 1 - KP_IV
> > 
> >             //byte[] pbData3 = new byte[8];
> > 
> >             //uint dwFlags6 = 0;
> > 
> >  
> > 
> >             //for (int i = 0; i < 8; i++)
> > 
> >             //    pbData3[i] = 0;
> > 
> >  
> > 
> >             //bool bln1 = CryptSetKeyParam(pnKey, dwParam, pbData3, dwFlags6);
> > 
> >  
> > 
> >             //erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >             bool bln2 = CryptDecrypt(pnKey, hHash, Final, dwFlags5, ref 
> > bufferArquivo, ref arquivoLen);
> > 
> >  
> > 
> >             erro = Marshal.GetLastWin32Error();
> > 
> >  
> > 
> >  
> > 
> > }
> > 
> >  
> > 
> >  
> > 
> >
date: Thu, 22 May 2008 08:46:01 -0700   author:   Marcio Campos

RE: CryptDecrypt with error 0x80090005   
Hi,

From what I see, there is no obvious reason for the CryptDecrypt to fail. 
The only explanation I have is that there is a limitation on the SafeSign CSP 
you are using. The same sequence of calls (in C++) executed with MS CSP and 
with a smart card CSP of another vendor (not SafeSign) goes well with no 
errors. 
I advise you to contact the SafeSign CSP vendor to see if they can help you.

-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"Marcio Campos" wrote:

> Thanks for you answer.
> 
> I can simplify the program according to your suggestion but we did a lot of 
> debbuging and:
> 
> 1) "For examples, instead of using an external file (texto.txt), use a 
> hard-coded 
> > buffer to simplify the problem analyze. "
> 
> The buffer is correct. We tryed alsoo with a hard coded buffer and the 
> result is same (fails).
> 
> 2) "Crypt function (not only the GetLastError) to be sure which function 
> > fails. "
> 
> The CryptEncrypt functions always fail. We verified with the debbuger. 
> 
> 3) "You must also verify the output buffer used in CryptEncrypt is larger 
> > enough to hold the result (don't forget that there will be paddings)."
> 
> The buffer is larger enough to hold the result.
> 
> To clarify a little more. All the other crypt functions works fine. The same 
> sequence of functions call are done in C++ and works OK.
> 
> I wonder if the Key Handler is in some kind of state that makes the function 
> CrypDecrypt Fails. See in the code that the Key Handler for Encrypt is the 
> same of the Decrypt.
> 
> Thanks for your help!
> 
> Cheers!!!
>
date: Thu, 22 May 2008 10:39:01 -0700   author:   Mounir IDRASSI am

RE: CryptDecrypt with error 0x80090005   
Mounir

I´m still strugling with the same error despite using CSP from Safesign or 
Microsoft. I wonder if it is possible to use CryptApi from a C# since the 
same code in C++ works whithout any problem.

Another possibility is that we are not defining the Cryptapi (dllimport) 
whit the correct type. Below is the code of the dllimport. Do you see any 
problem ?


[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        [return: MarshalAs(UnmanagedType.Bool)]

        static extern bool CryptAcquireContext( ref IntPtr hProv, string 
pszContainer,

                                                string pszProvider, uint 
dwProvType, uint dwFlags);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        static extern Boolean CryptGetUserKey( IntPtr hProv,

                                               uint dwKeySpec,

                                               ref IntPtr hKey);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        static extern Boolean CryptGetKeyParam( IntPtr hKey,

                                                uint dwParam,

                                                byte[] pbData,

                                                ref uint pdwDataLen,

                                                uint dwFlags);

        

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        static extern Boolean CryptSetKeyParam(IntPtr hKey,

                                                uint dwParam,

                                                byte[] pbData,

                                                uint dwFlags);

 

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        static extern bool CryptExportKey( IntPtr hKey,

                                           IntPtr hExpKey,

                                           Int32 dwBlobType,

                                           Int32 dwFlags,

                                           Byte[] pbData,

                                           ref Int32 pdwDataLen);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        public static extern bool CryptGenKey(IntPtr hProv, uint Algid, uint 
dwFlags, ref IntPtr phKey);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        public static extern bool CryptImportKey(IntPtr hProv, byte[] 
pbKeyData, int dwDataLen, IntPtr hPubKey, uint dwFlags, ref IntPtr hKey);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, 
int Final, uint dwFlags, byte[] pbData, ref int pdwDataLen, int dwBufLen);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, 
int Final, uint dwFlags, ref byte[] pbData, ref int pdwDataLen);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        public static extern bool CryptDuplicateKey(IntPtr hKey, ref IntPtr 
pdwReserved, uint dwFlags, ref IntPtr phKey);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        public static extern bool CryptDestroyKey(IntPtr phKey);

 

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]

        public static extern bool CryptReleaseContext(IntPtr hProv, uint 
dwFlags);

 

Thanks

Marcio


"Mounir IDRASSI" wrote:

> Hi,
> 
> From what I see, there is no obvious reason for the CryptDecrypt to fail. 
> The only explanation I have is that there is a limitation on the SafeSign CSP 
> you are using. The same sequence of calls (in C++) executed with MS CSP and 
> with a smart card CSP of another vendor (not SafeSign) goes well with no 
> errors. 
> I advise you to contact the SafeSign CSP vendor to see if they can help you.
> 
> -- 
> Mounir IDRASSI
> IDRIX
> http://www.idrix.fr
> 
> to reach : mounir_idrix_fr (replace the underscores with the at and dot 
> characters respectively)
> 
> 
> "Marcio Campos" wrote:
> 
> > Thanks for you answer.
> > 
> > I can simplify the program according to your suggestion but we did a lot of 
> > debbuging and:
> > 
> > 1) "For examples, instead of using an external file (texto.txt), use a 
> > hard-coded 
> > > buffer to simplify the problem analyze. "
> > 
> > The buffer is correct. We tryed alsoo with a hard coded buffer and the 
> > result is same (fails).
> > 
> > 2) "Crypt function (not only the GetLastError) to be sure which function 
> > > fails. "
> > 
> > The CryptEncrypt functions always fail. We verified with the debbuger. 
> > 
> > 3) "You must also verify the output buffer used in CryptEncrypt is larger 
> > > enough to hold the result (don't forget that there will be paddings)."
> > 
> > The buffer is larger enough to hold the result.
> > 
> > To clarify a little more. All the other crypt functions works fine. The same 
> > sequence of functions call are done in C++ and works OK.
> > 
> > I wonder if the Key Handler is in some kind of state that makes the function 
> > CrypDecrypt Fails. See in the code that the Key Handler for Encrypt is the 
> > same of the Decrypt.
> > 
> > Thanks for your help!
> > 
> > Cheers!!!
> > 
>
date: Tue, 27 May 2008 08:33:01 -0700   author:   Marcio Campos

RE: CryptDecrypt with error 0x80090005   
Hi Marcio,

I think the problem comes from the declaration of the type of parameter 
Final in CryptEncrypt and CryptDecrypt. You should declare it as "bool" not 
"int". Try with this and tell me if it corrects your problem.

-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"Marcio Campos" wrote:

> Mounir
> 
> I´m still strugling with the same error despite using CSP from Safesign or 
> Microsoft. I wonder if it is possible to use CryptApi from a C# since the 
> same code in C++ works whithout any problem.
> 
> Another possibility is that we are not defining the Cryptapi (dllimport) 
> whit the correct type. Below is the code of the dllimport. Do you see any 
> problem ?
> 
> 
> [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
> 
>         [return: MarshalAs(UnmanagedType.Bool)]
> 
>         static extern bool CryptAcquireContext( ref IntPtr hProv, string 
> pszContainer,
> 
>                                                 string pszProvider, uint 
> dwProvType, uint dwFlags);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         static extern Boolean CryptGetUserKey( IntPtr hProv,
> 
>                                                uint dwKeySpec,
> 
>                                                ref IntPtr hKey);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         static extern Boolean CryptGetKeyParam( IntPtr hKey,
> 
>                                                 uint dwParam,
> 
>                                                 byte[] pbData,
> 
>                                                 ref uint pdwDataLen,
> 
>                                                 uint dwFlags);
> 
>         
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         static extern Boolean CryptSetKeyParam(IntPtr hKey,
> 
>                                                 uint dwParam,
> 
>                                                 byte[] pbData,
> 
>                                                 uint dwFlags);
> 
>  
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         static extern bool CryptExportKey( IntPtr hKey,
> 
>                                            IntPtr hExpKey,
> 
>                                            Int32 dwBlobType,
> 
>                                            Int32 dwFlags,
> 
>                                            Byte[] pbData,
> 
>                                            ref Int32 pdwDataLen);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         public static extern bool CryptGenKey(IntPtr hProv, uint Algid, uint 
> dwFlags, ref IntPtr phKey);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         public static extern bool CryptImportKey(IntPtr hProv, byte[] 
> pbKeyData, int dwDataLen, IntPtr hPubKey, uint dwFlags, ref IntPtr hKey);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, 
> int Final, uint dwFlags, byte[] pbData, ref int pdwDataLen, int dwBufLen);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, 
> int Final, uint dwFlags, ref byte[] pbData, ref int pdwDataLen);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         public static extern bool CryptDuplicateKey(IntPtr hKey, ref IntPtr 
> pdwReserved, uint dwFlags, ref IntPtr phKey);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         public static extern bool CryptDestroyKey(IntPtr phKey);
> 
>  
> 
>         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> true)]
> 
>         public static extern bool CryptReleaseContext(IntPtr hProv, uint 
> dwFlags);
> 
>  
> 
> Thanks
> 
> Marcio
> 
> 
> "Mounir IDRASSI" wrote:
> 
> > Hi,
> > 
> > From what I see, there is no obvious reason for the CryptDecrypt to fail. 
> > The only explanation I have is that there is a limitation on the SafeSign CSP 
> > you are using. The same sequence of calls (in C++) executed with MS CSP and 
> > with a smart card CSP of another vendor (not SafeSign) goes well with no 
> > errors. 
> > I advise you to contact the SafeSign CSP vendor to see if they can help you.
> > 
> > -- 
> > Mounir IDRASSI
> > IDRIX
> > http://www.idrix.fr
> > 
> > to reach : mounir_idrix_fr (replace the underscores with the at and dot 
> > characters respectively)
> > 
> > 
> > "Marcio Campos" wrote:
> > 
> > > Thanks for you answer.
> > > 
> > > I can simplify the program according to your suggestion but we did a lot of 
> > > debbuging and:
> > > 
> > > 1) "For examples, instead of using an external file (texto.txt), use a 
> > > hard-coded 
> > > > buffer to simplify the problem analyze. "
> > > 
> > > The buffer is correct. We tryed alsoo with a hard coded buffer and the 
> > > result is same (fails).
> > > 
> > > 2) "Crypt function (not only the GetLastError) to be sure which function 
> > > > fails. "
> > > 
> > > The CryptEncrypt functions always fail. We verified with the debbuger. 
> > > 
> > > 3) "You must also verify the output buffer used in CryptEncrypt is larger 
> > > > enough to hold the result (don't forget that there will be paddings)."
> > > 
> > > The buffer is larger enough to hold the result.
> > > 
> > > To clarify a little more. All the other crypt functions works fine. The same 
> > > sequence of functions call are done in C++ and works OK.
> > > 
> > > I wonder if the Key Handler is in some kind of state that makes the function 
> > > CrypDecrypt Fails. See in the code that the Key Handler for Encrypt is the 
> > > same of the Decrypt.
> > > 
> > > Thanks for your help!
> > > 
> > > Cheers!!!
> > > 
> >
date: Tue, 27 May 2008 09:10:00 -0700   author:   Mounir IDRASSI am

RE: CryptDecrypt with error 0x80090005   
Mounir 

It still doesn´t work!

I get this message error:

"An unhandled exception of type 'System.ArgumentException' occurred in 
WindowsApplication1.exe

Additional information: Method's type signature is not Interop compatible."


"Mounir IDRASSI" wrote:

> Hi Marcio,
> 
> I think the problem comes from the declaration of the type of parameter 
> Final in CryptEncrypt and CryptDecrypt. You should declare it as "bool" not 
> "int". Try with this and tell me if it corrects your problem.
> 
> -- 
> Mounir IDRASSI
> IDRIX
> http://www.idrix.fr
> 
> to reach : mounir_idrix_fr (replace the underscores with the at and dot 
> characters respectively)
> 
> 
> "Marcio Campos" wrote:
> 
> > Mounir
> > 
> > I´m still strugling with the same error despite using CSP from Safesign or 
> > Microsoft. I wonder if it is possible to use CryptApi from a C# since the 
> > same code in C++ works whithout any problem.
> > 
> > Another possibility is that we are not defining the Cryptapi (dllimport) 
> > whit the correct type. Below is the code of the dllimport. Do you see any 
> > problem ?
> > 
> > 
> > [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
> > 
> >         [return: MarshalAs(UnmanagedType.Bool)]
> > 
> >         static extern bool CryptAcquireContext( ref IntPtr hProv, string 
> > pszContainer,
> > 
> >                                                 string pszProvider, uint 
> > dwProvType, uint dwFlags);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         static extern Boolean CryptGetUserKey( IntPtr hProv,
> > 
> >                                                uint dwKeySpec,
> > 
> >                                                ref IntPtr hKey);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         static extern Boolean CryptGetKeyParam( IntPtr hKey,
> > 
> >                                                 uint dwParam,
> > 
> >                                                 byte[] pbData,
> > 
> >                                                 ref uint pdwDataLen,
> > 
> >                                                 uint dwFlags);
> > 
> >         
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         static extern Boolean CryptSetKeyParam(IntPtr hKey,
> > 
> >                                                 uint dwParam,
> > 
> >                                                 byte[] pbData,
> > 
> >                                                 uint dwFlags);
> > 
> >  
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         static extern bool CryptExportKey( IntPtr hKey,
> > 
> >                                            IntPtr hExpKey,
> > 
> >                                            Int32 dwBlobType,
> > 
> >                                            Int32 dwFlags,
> > 
> >                                            Byte[] pbData,
> > 
> >                                            ref Int32 pdwDataLen);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         public static extern bool CryptGenKey(IntPtr hProv, uint Algid, uint 
> > dwFlags, ref IntPtr phKey);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         public static extern bool CryptImportKey(IntPtr hProv, byte[] 
> > pbKeyData, int dwDataLen, IntPtr hPubKey, uint dwFlags, ref IntPtr hKey);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, 
> > int Final, uint dwFlags, byte[] pbData, ref int pdwDataLen, int dwBufLen);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, 
> > int Final, uint dwFlags, ref byte[] pbData, ref int pdwDataLen);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         public static extern bool CryptDuplicateKey(IntPtr hKey, ref IntPtr 
> > pdwReserved, uint dwFlags, ref IntPtr phKey);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         public static extern bool CryptDestroyKey(IntPtr phKey);
> > 
> >  
> > 
> >         [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
> > true)]
> > 
> >         public static extern bool CryptReleaseContext(IntPtr hProv, uint 
> > dwFlags);
> > 
> >  
> > 
> > Thanks
> > 
> > Marcio
> > 
> > 
> > "Mounir IDRASSI" wrote:
> > 
> > > Hi,
> > > 
> > > From what I see, there is no obvious reason for the CryptDecrypt to fail. 
> > > The only explanation I have is that there is a limitation on the SafeSign CSP 
> > > you are using. The same sequence of calls (in C++) executed with MS CSP and 
> > > with a smart card CSP of another vendor (not SafeSign) goes well with no 
> > > errors. 
> > > I advise you to contact the SafeSign CSP vendor to see if they can help you.
> > > 
> > > -- 
> > > Mounir IDRASSI
> > > IDRIX
> > > http://www.idrix.fr
> > > 
> > > to reach : mounir_idrix_fr (replace the underscores with the at and dot 
> > > characters respectively)
> > > 
> > > 
> > > "Marcio Campos" wrote:
> > > 
> > > > Thanks for you answer.
> > > > 
> > > > I can simplify the program according to your suggestion but we did a lot of 
> > > > debbuging and:
> > > > 
> > > > 1) "For examples, instead of using an external file (texto.txt), use a 
> > > > hard-coded 
> > > > > buffer to simplify the problem analyze. "
> > > > 
> > > > The buffer is correct. We tryed alsoo with a hard coded buffer and the 
> > > > result is same (fails).
> > > > 
> > > > 2) "Crypt function (not only the GetLastError) to be sure which function 
> > > > > fails. "
> > > > 
> > > > The CryptEncrypt functions always fail. We verified with the debbuger. 
> > > > 
> > > > 3) "You must also verify the output buffer used in CryptEncrypt is larger 
> > > > > enough to hold the result (don't forget that there will be paddings)."
> > > > 
> > > > The buffer is larger enough to hold the result.
> > > > 
> > > > To clarify a little more. All the other crypt functions works fine. The same 
> > > > sequence of functions call are done in C++ and works OK.
> > > > 
> > > > I wonder if the Key Handler is in some kind of state that makes the function 
> > > > CrypDecrypt Fails. See in the code that the Key Handler for Encrypt is the 
> > > > same of the Decrypt.
> > > > 
> > > > Thanks for your help!
> > > > 
> > > > Cheers!!!
> > > > 
> > >
date: Wed, 28 May 2008 13:42:00 -0700   author:   Marcio Campos

RE: CryptDecrypt with error 0x80090005   
Hi Marcio,

I managed to write and test a .net wrapper for CryptoAPI that works very 
well with the set of functions you are using. You can download it from the 
following link : 

http://www.idrix.fr/Root/Samples/Capi.cs

I didn't use anything special so I guess you have a well hidden error in 
your code. 
Let me know if you still have a problem using my wrapper.

Cheers, 
-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"Marcio Campos" wrote:

> Mounir 
> 
> It still doesn´t work!
> 
> I get this message error:
> 
> "An unhandled exception of type 'System.ArgumentException' occurred in 
> WindowsApplication1.exe
> 
> Additional information: Method's type signature is not Interop compatible."
> 
>
date: Thu, 29 May 2008 04:13:01 -0700   author:   Mounir IDRASSI am

RE: CryptDecrypt with error 0x80090005   
Mounir
I changed the code and worked. The problem was that the definition of 
encrypt and decrypt was wrog. Besides the change suggested by you (boolen) I 
had to change the definition of the buffer for IntPtr and do all the 
necessary buffer allocation in the code. Below it is the code in case anybody 
needs it in the future. I got also ypur code.

Thank you very much

Cheers

MArcio

--------------- the code -----------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;

using System.Collections;
using System.IO;


namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }



        private Byte[] pbData = null;




        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = 
true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CryptAcquireContext( ref IntPtr hProv, string 
pszContainer,
                                                string pszProvider, uint 
dwProvType, uint dwFlags);

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        static extern Boolean CryptGetUserKey( IntPtr hProv,
                                               uint dwKeySpec,
                                               ref IntPtr hKey);

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        static extern Boolean CryptGetKeyParam( IntPtr hKey,
                                                uint dwParam,
                                                byte[] pbData,
                                                ref uint pdwDataLen,
                                                uint dwFlags);
        
        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        static extern Boolean CryptSetKeyParam(IntPtr hKey,
                                                uint dwParam,
                                                byte[] pbData,
                                                uint dwFlags);


        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        static extern bool CryptExportKey( IntPtr hKey,
                                           IntPtr hExpKey,
                                           Int32 dwBlobType,
                                           Int32 dwFlags,
                                           Byte[] pbData,
                                           ref Int32 pdwDataLen);

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        public static extern bool CryptGenKey(IntPtr hProv, uint Algid, uint 
dwFlags, ref IntPtr phKey);


        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        public static extern bool CryptImportKey(IntPtr hProv, byte[] 
pbKeyData, int dwDataLen, IntPtr hPubKey, uint dwFlags, ref IntPtr hKey);

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, 
bool Final, uint dwFlags, IntPtr pbData, ref uint pdwDataLen, uint dwBufLen);

        [DllImport("ADVAPI32.DLL", CharSet = CharSet.Auto, SetLastError = 
true)]
        public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, 
bool Final, uint dwFlags, IntPtr pbData, ref uint pdwDataLen);


        private void btnObterCertificadoDigital_Click(object sender, 
EventArgs e)
        {
            IntPtr hProv = new IntPtr();
            string pszContainer = null;
            string pszProvider = "SafeSign Basic Cryptographic Service 
Provider";
            uint dwProvType = 1; // "1 - PROV_RSA_FULL";
            uint dwFlags = 32;   // "8 - CRYPT_NEWKEYSET";


            int erro = 0;

            CryptAcquireContext(ref hProv, pszContainer, pszProvider, 
dwProvType, dwFlags);

            erro = Marshal.GetLastWin32Error();

            // Obtem a chave do cartao
            // =============================================================
            uint dwKeySpec = 2; // "1 - AT_KEYEXCHANGE"; "2 - AT_SIGNATURE";
            IntPtr hKey = new IntPtr();

            CryptGetUserKey(hProv, dwKeySpec, ref hKey);

            erro = Marshal.GetLastWin32Error();

            // Obtem os parametros da chave
            // =============================================================
            uint dwParam = 26;  // "26 - KP_CERTIFICATE"
            byte[] pbData = null;
            uint pdwDataLen = 0;
            uint dwFlags2 = 0;

            CryptGetKeyParam(hKey, dwParam, pbData, ref pdwDataLen, dwFlags2);

            pbData = new byte[pdwDataLen];

            CryptGetKeyParam(hKey, dwParam, pbData, ref pdwDataLen, dwFlags2);

            erro = Marshal.GetLastWin32Error();

            GravarArquivo(pbData, "c:\\certificado.cer");            
            
        }


        private static void GravarArquivo(byte[] imagem, string nomeArquivo)
        {
            BinaryWriter lobjbinWriter;

            try
            {
                lobjbinWriter = new BinaryWriter(File.Open(nomeArquivo, 
FileMode.Create));
                lobjbinWriter.Write(imagem);
                lobjbinWriter.BaseStream.Close();
                lobjbinWriter.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível gravar o arquivo: " + 
ex.Message);
            }
        }

        private void btnObterChavePublica_Click(object sender, EventArgs e)
        {
            IntPtr hProv = new IntPtr();
            string pszContainer = null;
            string pszProvider = "SafeSign Standard Cryptographic Service 
Provider";
            uint dwProvType = 1; // "1 - PROV_RSA_FULL";
            uint dwFlags = 32;   // "8 - CRYPT_NEWKEYSET";


            int erro = 0;

            CryptAcquireContext(ref hProv, pszContainer, pszProvider, 
dwProvType, dwFlags);

            erro = Marshal.GetLastWin32Error();

            // Obtem a chave do cartao
            // =============================================================
            uint dwKeySpec = 2; // "1 - AT_KEYEXCHANGE"; "2 - AT_SIGNATURE";
            IntPtr hKey = new IntPtr();

            CryptGetUserKey(hProv, dwKeySpec, ref hKey);

            erro = Marshal.GetLastWin32Error();



            // Obtem a chave pública
            // =============================================================

            IntPtr hExpKey = new IntPtr();
            Int32 dwBlobType = 6;   //"6 - PUBLICKEYBLOB";
            Int32 dwFlags3 = 0;
            //Byte[] pbData = null;
            Int32 pdwDataLen = 0;

            CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags3, pbData, ref 
pdwDataLen);

            erro = Marshal.GetLastWin32Error();

            pbData = new byte[pdwDataLen];

            CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags3, pbData, ref 
pdwDataLen);

            erro = Marshal.GetLastWin32Error();

            GravarArquivo(pbData, "c:\\chave_publica.blb");

        }

        private void btnGerarChaveTDES_Click(object sender, EventArgs e)
        {
            IntPtr hProv = new IntPtr();
            string pszContainer = null;
            string pszProvider = null;
            uint dwProvType = 1; // "1 - PROV_RSA_FULL";
            uint dwFlags = 0;   // "8 - CRYPT_NEWKEYSET";

            int erro = 0;

            CryptAcquireContext(ref hProv, pszContainer, pszProvider, 
dwProvType, dwFlags);

            erro = Marshal.GetLastWin32Error();

            // Gera a chave TDES
            // =============================================================
            //IntPtr pnKey = new IntPtr();
            IntPtr pnKey = new IntPtr();
            uint Aldid = ((3 << 13) | (3 << 9) | (3));
            uint dwFlags2 = 1;  //1 - CRYPT EXPORTABLE

            CryptGenKey(hProv, Aldid, dwFlags2, ref pnKey);

            erro = Marshal.GetLastWin32Error();



            // Importa a chava para o cartão
            // =============================================================
            IntPtr hExpKey = new IntPtr();
            IntPtr nPubKey = new IntPtr();
            uint dwFlags3 = 0;

            // CryptImportKey(hProv, pbData, pbData.Length, nPubKey, 
dwFlags3, ref hExpKey);

            // erro = Marshal.GetLastWin32Error();

            // Exporta a chave
            // =============================================================
            Int32 dwBlobType = 1;   //"1 - SIMPLEBLOB";
            Int32 dwFlags4 = 0;
            Byte[] pbData2 = null;
            Int32 pdwDataLen = 0;

            // CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, null, 
ref pdwDataLen);

            // erro = Marshal.GetLastWin32Error();

            // pbData2 = new byte[pdwDataLen];

            // CryptExportKey(pnKey, hExpKey, dwBlobType, dwFlags4, pbData2, 
ref pdwDataLen);

            // erro = Marshal.GetLastWin32Error();

            // GravarArquivo(pbData2, "c:\\BlobTDes.blb");


            // Ler arquivo texto e encriptar
            // =============================================================
            IntPtr hHash = new IntPtr(0);
            bool Final = true;  // ultimo bloco ou não
            uint dwFlags5 = 0;


            //byte[] bufferArquivo = new byte[11027 + 130];
            byte[] bufferArquivo = new byte[128];
            byte[] arquivo = LerArquivo("c:\\texto.txt");
            int arquivoLen = arquivo.Length;

            // arquivo.CopyTo(bufferArquivo, 0);

           uint dwBufLen = (uint) arquivo.Length;
           IntPtr pbBuffer = IntPtr.Zero;

            pbBuffer = Marshal.AllocHGlobal(arquivo.Length + 256 );
            Marshal.Copy(arquivo, 0, pbBuffer, arquivo.Length);
            uint length = (uint)arquivo.Length + 256;
            CryptEncrypt(pnKey, hHash, Final, dwFlags5, pbBuffer, ref 
dwBufLen, length);

            erro = Marshal.GetLastWin32Error();

            //byte[] aux = new byte[arquivoLen];
            

            ////GravarArquivo(bufferArquivo, "c:\\texto_cripto.txt");
            //GravarArquivo(aux, "c:\\texto_cripto.txt");


            //// Zera o vetor de incializaçao
            //// =============================================================
            //uint dwParam = 1;   // 1 - KP_IV
            //byte[] pbData3 = new byte[8];
            //uint dwFlags6 = 0;

            //for (int i = 0; i < 8; i++)
            //    pbData3[i] = 0;

            //bool bln1 = CryptSetKeyParam(pnKey, dwParam, pbData3, dwFlags6);

            byte[] arquivo2 = new byte[256];         
            length=dwBufLen;
            CryptDecrypt(pnKey, IntPtr.Zero, Final, 0, pbBuffer, ref length);

            erro = Marshal.GetLastWin32Error();
            Marshal.Copy(pbBuffer, arquivo2, 0,(int) length);
            
            System.IO.File.WriteAllText("c:\\texto_descripto.txt", 
System.Text.Encoding.ASCII.GetString(arquivo2));


        }


        public void Gravar(string mensagem, string _arquivo)
        {
            StreamWriter swrite;

            try
            {
                swrite = new StreamWriter(_arquivo, true);
                swrite.WriteLine(mensagem);
                swrite.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }




        public static byte[] LerArquivo(string nomeArquivo)
        {
            BinaryReader lobjbinReader;
            byte[] b;

            try
            {
                lobjbinReader = new BinaryReader(File.Open(nomeArquivo, 
FileMode.Open));
                b = 
lobjbinReader.ReadBytes(int.Parse(lobjbinReader.BaseStream.Length.ToString()));
                lobjbinReader.BaseStream.Close();
                lobjbinReader.Close();

                return b;
            }
            catch (Exception ex)
            {
                throw new Exception("Não foi possível ler arquivo: " + 
ex.Message);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {

            IntPtr hProv = new IntPtr();
            string pszContainer = null;
            string pszProvider = "SafeSign Standard Cryptographic Service 
Provider";
            uint dwProvType = 1; // "1 - PROV_RSA_FULL";
            uint dwFlags = 32;   // "8 - CRYPT_NEWKEYSET";
            bool bln;

            int erro = 0;

            bln = CryptAcquireContext(ref hProv, pszContainer, pszProvider, 
dwProvType, dwFlags);

            erro = Marshal.GetLastWin32Error();

            // Obtem a chave do cartao
            // =============================================================
            uint dwKeySpec = 1; // "1 - AT_KEYEXCHANGE"; "2 - AT_SIGNATURE";
            IntPtr hKey = new IntPtr();

            CryptGetUserKey(hProv, dwKeySpec, ref hKey);

            erro = Marshal.GetLastWin32Error();



            // Importa a chava para o cartão
            // =============================================================
            IntPtr hImpKey = new IntPtr(0);
            uint dwFlags3 = 0;
            Byte[] pbData2 = null;

            IntPtr hHash = new IntPtr(0);
            bool Final = true;  // ultimo bloco ou não
            uint dwFlags5 = 0;

            pbData2 = LerArquivo("c:\\BlobTDes.blb");

            bln = CryptImportKey(hProv, pbData2, pbData2.Length, hKey, 
dwFlags3, ref hImpKey);

            erro = Marshal.GetLastWin32Error();


            // Zera o vetor de incializaçao
            // =============================================================
            uint dwParam = 1;   // 1 - KP_IV
            byte[] pbData = new byte[8];
            uint dwFlags6 = 0;

            for (int i = 0; i < 8; i++)
                pbData[i] = 0;


            CryptSetKeyParam(hImpKey, dwParam, pbData, dwFlags6);

            //erro = Marshal.GetLastWin32Error();


            // Le o arquivo encriptado
            // =============================================================

            byte[] bufferArquivo = new byte[11027 + 400];
            byte[] arquivo = LerArquivo("c:\\texto_cripto.txt");
            int arquivoLen = arquivo.Length;

            arquivo.CopyTo(bufferArquivo, 0);

            int dwBufLen = bufferArquivo.Length;
            Final = true;


            // Grava o arquivo dencriptado
            // =============================================================

       //    bln = CryptDecrypt(hImpKey, hHash, Final, dwFlags5, pb, ref 
arquivoLen);

            erro = Marshal.GetLastWin32Error();

            GravarArquivo(bufferArquivo, "c:\\texto_decripto.txt");

            
        }




    }
}

Mounir IDRASSI" wrote:

> Hi Marcio,
> 
> I managed to write and test a .net wrapper for CryptoAPI that works very 
> well with the set of functions you are using. You can download it from the 
> following link : 
> 
> http://www.idrix.fr/Root/Samples/Capi.cs
> 
> I didn't use anything special so I guess you have a well hidden error in 
> your code. 
> Let me know if you still have a problem using my wrapper.
> 
> Cheers, 
> -- 
> Mounir IDRASSI
> IDRIX
> http://www.idrix.fr
> 
> to reach : mounir_idrix_fr (replace the underscores with the at and dot 
> characters respectively)
> 
> 
> "Marcio Campos" wrote:
> 
> > Mounir 
> > 
> > It still doesn´t work!
> > 
> > I get this message error:
> > 
> > "An unhandled exception of type 'System.ArgumentException' occurred in 
> > WindowsApplication1.exe
> > 
> > Additional information: Method's type signature is not Interop compatible."
> > 
> >
date: Thu, 29 May 2008 07:28:02 -0700   author:   Marcio Campos

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us