C# server side (encode) -> C++ client side (decode) ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jtfaulk@eudoramail.com

    #1

    C# server side (encode) -> C++ client side (decode) ?

    I need to encode some information on the server side using ASP.NET with
    C#; sending via HTTP to a client side application, that needs to be
    decoded in an MFC C++ application.

    I'm not sure if I can encode something using:

    C#: System.Security .Cryptography (to encode)

    and

    C++: wincrypt.h (to decode)

    Does anybody have any idea about this? Thank you in advance; it is
    greatly appreciated.

    J

  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: C# server side (encode) -> C++ client side (decode) ?

    J,

    Sure you can. The classes in the System.Security .Cryptography namespace
    use well established algorithms to encrypt/decrypt information. You just
    have to use the same algorithms in your C++ code (which are supported, by
    the way), along with the same key and iv values for encryption/decryption.

    Hope this helps.


    --
    - Nicholas Paldino [.NET/C# MVP]
    - mvp@spam.guard. caspershouse.co m

    <jtfaulk@eudora mail.com> wrote in message
    news:1135116520 .216826.228810@ f14g2000cwb.goo glegroups.com.. .[color=blue]
    >I need to encode some information on the server side using ASP.NET with
    > C#; sending via HTTP to a client side application, that needs to be
    > decoded in an MFC C++ application.
    >
    > I'm not sure if I can encode something using:
    >
    > C#: System.Security .Cryptography (to encode)
    >
    > and
    >
    > C++: wincrypt.h (to decode)
    >
    > Does anybody have any idea about this? Thank you in advance; it is
    > greatly appreciated.
    >
    > J
    >[/color]


    Comment

    • jtfaulk@eudoramail.com

      #3
      Re: C# server side (encode) -&gt; C++ client side (decode) ?

      Ok, So my code is listed below. I'm not sure where to put the iv value
      for the C++ portion:

      I'm trying to encrypt a piece of information (a string of text from an
      ..INI file) on the server side (C# .net) and pass that information to
      the client side app which has to decrypt it. I'm trying to use (in c#)
      the System.Security .Cryptography and in c++ the wincrypt.h file. I'm
      not sure if this is possible (although I believe it is); so I was
      wondering if anybody had any ideas?

      The C# Server Code:

      // -----------------------------------------------------------
      // ENCRYPT (C# SERVER SIDE)
      // -----------------------------------------------------------
      using System.Security .Cryptography;
      private string Encrypt_Try2(st ring strKey, string strText)
      {
      PasswordDeriveB ytes cdk = new PasswordDeriveB ytes(strKey, null);

      // generate an RC2 key
      byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
      byte[] key = cdk.CryptDerive Key("RC2", "MD5", 128, iv);
      Console.WriteLi ne(key.Length * 8);

      // setup an RC2 object to encrypt with the derived key
      RC2CryptoServic eProvider rc2 = new RC2CryptoServic eProvider();
      rc2.Key = key;
      rc2.IV = new byte[] { 21, 22, 23, 24, 25, 26, 27, 28};

      // now encrypt with it
      byte[] plaintext = Encoding.UTF8.G etBytes(strText );
      MemoryStream ms = new MemoryStream();
      CryptoStream cs = new CryptoStream(ms , rc2.CreateEncry ptor(),
      CryptoStreamMod e.Write);

      cs.Write(plaint ext, 0, plaintext.Lengt h);
      cs.Close();
      byte[] encrypted = ms.ToArray();

      // Convert to Base64
      string txtOut = Convert.ToBase6 4String(encrypt ed);

      // THIS IS THE ENCRYPTED TEXT
      return txtOut;
      }

      // -----------------------------------------------------------
      // DECRYPT (FOR VERIFICATION - (C# SERVER SIDE))
      // -----------------------------------------------------------
      private string Decrypt_Try2(st ring strKey, string strText)
      {
      PasswordDeriveB ytes cdk = new PasswordDeriveB ytes(strKey, null);

      // generate an RC2 key
      byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
      byte[] key = cdk.CryptDerive Key("RC2", "MD5", 128, iv);
      Console.WriteLi ne(key.Length * 8);

      // setup an RC2 object to encrypt with the derived key
      RC2CryptoServic eProvider rc2 = new RC2CryptoServic eProvider();
      rc2.Key = key;
      rc2.IV = new byte[] { 21, 22, 23, 24, 25, 26, 27, 28};

      // now encrypt with it
      //byte[] plaintext = Encoding.UTF8.G etBytes(strText );
      byte[] plaintext = Convert.FromBas e64String(strTe xt);
      MemoryStream ms = new MemoryStream();
      CryptoStream cs = new CryptoStream(ms , rc2.CreateDecry ptor(),
      CryptoStreamMod e.Write);

      cs.Write(plaint ext, 0, plaintext.Lengt h);
      cs.Close();
      byte[] encrypted = ms.ToArray();

      System.Text.Enc oding encoding = System.Text.Enc oding.UTF8;

      // THIS IS THE DECRYPTED TEXT
      return encoding.GetStr ing(encrypted);

      //this.txtOut.Tex t = txtOut;
      }


      // -----------------------------------------------------------
      // DECRYPT (C++ CLIENT SIDE)
      // -----------------------------------------------------------

      CString CJCrypt::Decryp t(char *key, char *txtOut)
      {
      char *szPassword = key;

      CBase64Utils bu;
      int iTxtOutLen = strlen(txtOut);
      char *result = bu.Decode(txtOu t, &iTxtOutLen) ;

      DWORD dwBufLen = 1+strlen(result );
      HCRYPTPROV hCryptProv;
      HCRYPTKEY hKey;
      HCRYPTHASH hHashKey;
      DWORD sts=0;
      DWORD errc = 0;

      sts = CryptAcquireCon text(&hCryptPro v, NULL, MS_ENHANCED_PRO V,
      PROV_RSA_FULL, 0);
      if(sts == 0) errc=GetLastErr or();

      sts = CryptCreateHash (hCryptProv, CALG_MD5, 0, 0, &hHashKey);
      if(sts == 0) errc=GetLastErr or();

      sts = CryptHashData(h HashKey, (BYTE *)szPassword,
      strlen(szPasswo rd), 0);
      if(sts == 0) errc=GetLastErr or();

      //sts = CryptDeriveKey( hCryptProv, CALG_DES, hHashKey, (56)<<16,
      &hKey);

      sts = CryptDeriveKey( hCryptProv, CALG_RC2, hHashKey, 128, &hKey);
      //sts = CryptDeriveKey( hCryptProv, CALG_3DES, hHashKey, (168)<<16,
      &hKey);
      //sts = CryptDeriveKey( hCryptProv, CALG_RC4, hHashKey, (56)<<16,
      &hKey);
      if(sts == 0) errc=GetLastErr or();

      DWORD dwCryptBuffLen = dwBufLen;
      sts = CryptEncrypt(hK ey,0,TRUE,0,NUL L,&dwCryptBuffL en,0);
      BYTE *bCryptoBuffer = new BYTE[dwCryptBuffLen];
      memset(bCryptoB uffer,0,dwCrypt BuffLen);
      memcpy(bCryptoB uffer,result,dw BufLen + 3);

      sts = CryptDecrypt(hK ey, 0, TRUE,0,(BYTE *)result,
      &dwCryptBuffLen );

      if(sts == 0) errc=GetLastErr or();
      // else do something with the dwBufLen bytes of encrypted data in
      bCryptoBuffer

      sts = CryptDestroyKey (hKey);
      sts = CryptDestroyHas h(hHashKey);
      sts = CryptReleaseCon text(hCryptProv , 0);

      CString strOut;
      strOut.Format(" %s", result);

      return strOut;

      }

      // -----------------------------------------------------------
      // ENCRYPT (FOR VERFICATION - (C++ CLIENT SIDE))
      // -----------------------------------------------------------
      CString CJCrypt::Encryp t(char *key, char *txtIn)
      {
      char *szPassword = key;

      DWORD dwBufLen = 1+strlen(txtIn) ;
      HCRYPTPROV hCryptProv;
      HCRYPTKEY hKey;
      HCRYPTHASH hHashKey;
      DWORD sts=0;
      DWORD errc = 0;

      sts = CryptAcquireCon text(&hCryptPro v, NULL, MS_ENHANCED_PRO V,
      PROV_RSA_FULL, 0);
      if(sts == 0) errc=GetLastErr or();

      sts = CryptCreateHash (hCryptProv, CALG_MD5, 0, 0, &hHashKey);
      if(sts == 0) errc=GetLastErr or();

      sts = CryptHashData(h HashKey, (BYTE *)szPassword,
      strlen(szPasswo rd), 0);
      if(sts == 0) errc=GetLastErr or();

      //sts = CryptDeriveKey( hCryptProv, CALG_DES, hHashKey, (56)<<16,
      &hKey);
      sts = CryptDeriveKey( hCryptProv, CALG_RC2, hHashKey, 128, &hKey);
      //sts = CryptDeriveKey( hCryptProv, CALG_3DES, hHashKey, (168)<<16,
      &hKey);
      //sts = CryptDeriveKey( hCryptProv, CALG_RC4, hHashKey, (56)<<16,
      &hKey);
      if(sts == 0) errc=GetLastErr or();

      DWORD dwCryptBuffLen = dwBufLen;
      sts = CryptEncrypt(hK ey,0,TRUE,0,NUL L,&dwCryptBuffL en,0);
      BYTE *bCryptoBuffer = new BYTE[dwCryptBuffLen];
      memset(bCryptoB uffer,0,dwCrypt BuffLen);
      memcpy(bCryptoB uffer,txtIn,dwB ufLen);

      sts = CryptEncrypt(hK ey, 0, TRUE, 0, bCryptoBuffer, &dwBufLen,
      dwCryptBuffLen) ;

      // Convert To Base64
      CBase64Utils bu;
      char *result = bu.Encode((char *)bCryptoBuffer , dwBufLen + 1);

      if(sts == 0) errc=GetLastErr or();
      // else do something with the dwBufLen bytes of encrypted data in
      bCryptoBuffer

      sts = CryptDestroyKey (hKey);
      sts = CryptDestroyHas h(hHashKey);
      sts = CryptReleaseCon text(hCryptProv , 0);

      CString strOut;
      strOut.Format(" %s", result);
      return strOut;
      }

      Both the c# and c++ encrypt/decrypt work with them selves (i.e. I can
      encrypt and decrypt things using only the c++ OR the C#, but I cannot
      encrypt with C# and decrypt with C++). I'm not sure this is possible
      and I just don't have the parameters set up correctly; or if they use
      completely separate algorythms and will not work.

      Does anybody have any idea?

      Thank you very much

      Nicholas Paldino [.NET/C# MVP] wrote:[color=blue]
      > J,
      >
      > Sure you can. The classes in the System.Security .Cryptography namespace
      > use well established algorithms to encrypt/decrypt information. You just
      > have to use the same algorithms in your C++ code (which are supported, by
      > the way), along with the same key and iv values for encryption/decryption.
      >
      > Hope this helps.
      >
      >
      > --
      > - Nicholas Paldino [.NET/C# MVP]
      > - mvp@spam.guard. caspershouse.co m
      >
      > <jtfaulk@eudora mail.com> wrote in message
      > news:1135116520 .216826.228810@ f14g2000cwb.goo glegroups.com.. .[color=green]
      > >I need to encode some information on the server side using ASP.NET with
      > > C#; sending via HTTP to a client side application, that needs to be
      > > decoded in an MFC C++ application.
      > >
      > > I'm not sure if I can encode something using:
      > >
      > > C#: System.Security .Cryptography (to encode)
      > >
      > > and
      > >
      > > C++: wincrypt.h (to decode)
      > >
      > > Does anybody have any idea about this? Thank you in advance; it is
      > > greatly appreciated.
      > >
      > > J
      > >[/color][/color]

      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: C# server side (encode) -&gt; C++ client side (decode) ?

        <jtfaulk@eudora mail.com> wrote:[color=blue]
        > Ok, So my code is listed below. I'm not sure where to put the iv value
        > for the C++ portion:
        >
        > I'm trying to encrypt a piece of information (a string of text from an
        > .INI file) on the server side (C# .net) and pass that information to
        > the client side app which has to decrypt it. I'm trying to use (in c#)
        > the System.Security .Cryptography and in c++ the wincrypt.h file. I'm
        > not sure if this is possible (although I believe it is); so I was
        > wondering if anybody had any ideas?[/color]

        Having had a brief look at the C++ API, I believe you want to call
        CryptSetKeyPara m, passing in KP_IV as the second parameter.

        --
        Jon Skeet - <skeet@pobox.co m>
        http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
        If replying to the group, please do not mail me too

        Comment

        • jtfaulk@eudoramail.com

          #5
          Re: C# server side (encode) -&gt; C++ client side (decode) ?

          Yeah, the problem is that I'm unable to generate the same key on both
          c# and c++. This is the problem - does anybody have any ideas how to
          solve this?



          Jon wrote:[color=blue]
          > <jtfaulk@eudora mail.com> wrote:[color=green]
          > > Ok, So my code is listed below. I'm not sure where to put the iv value
          > > for the C++ portion:
          > >
          > > I'm trying to encrypt a piece of information (a string of text from an
          > > .INI file) on the server side (C# .net) and pass that information to
          > > the client side app which has to decrypt it. I'm trying to use (in c#)
          > > the System.Security .Cryptography and in c++ the wincrypt.h file. I'm
          > > not sure if this is possible (although I believe it is); so I was
          > > wondering if anybody had any ideas?[/color]
          >
          > Having had a brief look at the C++ API, I believe you want to call
          > CryptSetKeyPara m, passing in KP_IV as the second parameter.
          >
          > --
          > Jon Skeet - <skeet@pobox.co m>
          > http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
          > If replying to the group, please do not mail me too[/color]

          Comment

          • Jon Skeet [C# MVP]

            #6
            Re: C# server side (encode) -&gt; C++ client side (decode) ?

            <jtfaulk@eudora mail.com> wrote:[color=blue]
            > Yeah, the problem is that I'm unable to generate the same key on both
            > c# and c++. This is the problem - does anybody have any ideas how to
            > solve this?[/color]

            Hang on - you're unable to generate the same *key*, or the same IV? You
            shouldn't be generating the key at all - that should be known
            information.

            --
            Jon Skeet - <skeet@pobox.co m>
            http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
            If replying to the group, please do not mail me too

            Comment

            • jtfaulk@eudoramail.com

              #7
              Re: C# server side (encode) -&gt; C++ client side (decode) ?

              Ok, let say I assign the key (ie. hard code). That's fine; but I'm not
              even sure how to do this. I simply cannot pass the same key to the c#
              anc c++ encryption functions; therefore the output is not the same.

              Do you have any ideas as to how to accomplish this? Let's say I want
              to start (in c#) with the key:

              byte[] testKey = {32, 44, 185, 98, 172, 89, 7, 91, 150, 75, 7, 21, 45,
              35, 75, 112};

              I have tried this and it works fine (it encrypts the original text).
              But my problem is that now I cannot pass this same key to the
              encryption process in c++.

              How can I turn the above key into HCRYPTKEY and get the same results?

              Thank you,

              Jon wrote:[color=blue]
              > <jtfaulk@eudora mail.com> wrote:[color=green]
              > > Yeah, the problem is that I'm unable to generate the same key on both
              > > c# and c++. This is the problem - does anybody have any ideas how to
              > > solve this?[/color]
              >
              > Hang on - you're unable to generate the same *key*, or the same IV? You
              > shouldn't be generating the key at all - that should be known
              > information.
              >
              > --
              > Jon Skeet - <skeet@pobox.co m>
              > http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
              > If replying to the group, please do not mail me too[/color]

              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: C# server side (encode) -&gt; C++ client side (decode) ?

                <jtfaulk@eudora mail.com> wrote:[color=blue]
                > Ok, let say I assign the key (ie. hard code). That's fine; but I'm not
                > even sure how to do this. I simply cannot pass the same key to the c#
                > anc c++ encryption functions; therefore the output is not the same.
                >
                > Do you have any ideas as to how to accomplish this? Let's say I want
                > to start (in c#) with the key:
                >
                > byte[] testKey = {32, 44, 185, 98, 172, 89, 7, 91, 150, 75, 7, 21, 45,
                > 35, 75, 112};
                >
                > I have tried this and it works fine (it encrypts the original text).
                > But my problem is that now I cannot pass this same key to the
                > encryption process in c++.
                >
                > How can I turn the above key into HCRYPTKEY and get the same results?[/color]

                I'm afraid I don't know - I think you'd be best off asking that in a
                Win32-specific group (or a Windows Security/Cryptography group).

                --
                Jon Skeet - <skeet@pobox.co m>
                http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                If replying to the group, please do not mail me too

                Comment

                Working...