Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Encryption/Decryption porting from .NET

Encryption/Decryption porting from .NET

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 487 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Toto83
    wrote on 13 Nov 2024, 15:10 last edited by
    #1

    Hello to all,

    I need your help about encryption/decryption with Qt 6.7.2

    I'm porting an existing project from .NET (WPF C#) to Qt , the old project is not made by me and I have not experience with encryption.
    I don't know how to rewrite these two function:

    public static string EncryptText(string plainText) {
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
            var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
            var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
    
            byte[] cipherTextBytes;
    
            using (var memoryStream = new MemoryStream()) {
                    using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)){
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            cipherTextBytes = memoryStream.ToArray();
                            cryptoStream.Close();
                    }
                    memoryStream.Close();
            }
            return Convert.ToBase64String(cipherTextBytes);
    }
    
    public static string DecryptText(string encryptedText) {
            byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
            byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
            var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
    
            var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
            var memoryStream = new MemoryStream(cipherTextBytes);
            var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
    
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
            memoryStream.Close();
            cryptoStream.Close();
    
            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
    }
    

    Obviously it is required to have the same functions for backwards compatibility reasons.

    Someone knows how to do this?

    Thanks in advance.

    J 1 Reply Last reply 13 Nov 2024, 15:25
    0
    • T Toto83
      13 Nov 2024, 15:10

      Hello to all,

      I need your help about encryption/decryption with Qt 6.7.2

      I'm porting an existing project from .NET (WPF C#) to Qt , the old project is not made by me and I have not experience with encryption.
      I don't know how to rewrite these two function:

      public static string EncryptText(string plainText) {
              byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
              byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
              var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
              var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
      
              byte[] cipherTextBytes;
      
              using (var memoryStream = new MemoryStream()) {
                      using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)){
                              cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                              cryptoStream.FlushFinalBlock();
                              cipherTextBytes = memoryStream.ToArray();
                              cryptoStream.Close();
                      }
                      memoryStream.Close();
              }
              return Convert.ToBase64String(cipherTextBytes);
      }
      
      public static string DecryptText(string encryptedText) {
              byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
              byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
              var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
      
              var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
              var memoryStream = new MemoryStream(cipherTextBytes);
              var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
              byte[] plainTextBytes = new byte[cipherTextBytes.Length];
      
              int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
              memoryStream.Close();
              cryptoStream.Close();
      
              return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
      }
      

      Obviously it is required to have the same functions for backwards compatibility reasons.

      Someone knows how to do this?

      Thanks in advance.

      J Offline
      J Offline
      JonB
      wrote on 13 Nov 2024, 15:25 last edited by JonB
      #2

      @Toto83
      You will have much to do!

      Assuming you are not going to try to find an existing project which offers a robust/usable C# binding for Qt. (There may be such a binding out there, but make sure it is fully up-to-date with Qt 6.whatever, which it may well not be.)

      Before you start you will need equivalents for .NET's Rfc2898DeriveBytes and RijndaelManaged. (I assume to be workable e.g. with existing encrypted data you will need this encryption.) I have not looked at the latter, but I glanced at the former.

      • Are you aware that, by default/the way your code is, Rfc2898DeriveBytes uses SHA1 and is deprecated by MS/.NET etc.?

      The Rfc2898DeriveBytes class defaults to using the SHA1 algorithm. When instantiating an Rfc2898DeriveBytes object, you should specify a hash algorithm of SHA256 or higher.

      • You might want to read through https://medium.com/@joaomvfsantos/writing-c-s-rfc2898derivebytes-in-php-88fa8c096dcb for some understanding/help if you are going to have to write an equivalent in C++. I don't know whether that article takes into account SHA1 vs SHA256.

      • Also https://stackoverflow.com/questions/55015935/equivalent-of-rfc2898derivebytes-in-c-without-using-clr or https://www.example-code.com/cpp/pbkdf2_duplicate_Rfc2898DeriveBytes.asp.

      Of course if you do not require to use Rfc2898DeriveBytes and could substitute an alternative encrypt/decrypt that is a different matter.

      P 1 Reply Last reply 13 Nov 2024, 15:32
      1
      • J JonB
        13 Nov 2024, 15:25

        @Toto83
        You will have much to do!

        Assuming you are not going to try to find an existing project which offers a robust/usable C# binding for Qt. (There may be such a binding out there, but make sure it is fully up-to-date with Qt 6.whatever, which it may well not be.)

        Before you start you will need equivalents for .NET's Rfc2898DeriveBytes and RijndaelManaged. (I assume to be workable e.g. with existing encrypted data you will need this encryption.) I have not looked at the latter, but I glanced at the former.

        • Are you aware that, by default/the way your code is, Rfc2898DeriveBytes uses SHA1 and is deprecated by MS/.NET etc.?

        The Rfc2898DeriveBytes class defaults to using the SHA1 algorithm. When instantiating an Rfc2898DeriveBytes object, you should specify a hash algorithm of SHA256 or higher.

        • You might want to read through https://medium.com/@joaomvfsantos/writing-c-s-rfc2898derivebytes-in-php-88fa8c096dcb for some understanding/help if you are going to have to write an equivalent in C++. I don't know whether that article takes into account SHA1 vs SHA256.

        • Also https://stackoverflow.com/questions/55015935/equivalent-of-rfc2898derivebytes-in-c-without-using-clr or https://www.example-code.com/cpp/pbkdf2_duplicate_Rfc2898DeriveBytes.asp.

        Of course if you do not require to use Rfc2898DeriveBytes and could substitute an alternative encrypt/decrypt that is a different matter.

        P Offline
        P Offline
        Pl45m4
        wrote on 13 Nov 2024, 15:32 last edited by Pl45m4
        #3

        @JonB said in Encryption/Decryption porting from .NET:

        Assuming you are not going to try to find an existing project which offers a robust/usable C# binding for Qt.

        Qt has .NET bindings... (urgh) :D

        @Toto83

        En-/Decryption using the Rijndael Algorithm is symmetric AES.
        (Taking IT Security in University paid off here :D)

        Lots of C++ Crypto or AES stuff out there.

        • https://github.com/SergeyBel/AES
        • https://github.com/weidai11/cryptopp

        @Toto83 said in Encryption/Decryption porting from .NET:

        Obviously it is required to have the same functions for backwards compatibility reasons.

        Well... good luck with that
        But you can write a function DecryptText yourself, which, internally uses a C++ Cypto library.


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        J 1 Reply Last reply 13 Nov 2024, 15:36
        1
        • P Pl45m4
          13 Nov 2024, 15:32

          @JonB said in Encryption/Decryption porting from .NET:

          Assuming you are not going to try to find an existing project which offers a robust/usable C# binding for Qt.

          Qt has .NET bindings... (urgh) :D

          @Toto83

          En-/Decryption using the Rijndael Algorithm is symmetric AES.
          (Taking IT Security in University paid off here :D)

          Lots of C++ Crypto or AES stuff out there.

          • https://github.com/SergeyBel/AES
          • https://github.com/weidai11/cryptopp

          @Toto83 said in Encryption/Decryption porting from .NET:

          Obviously it is required to have the same functions for backwards compatibility reasons.

          Well... good luck with that
          But you can write a function DecryptText yourself, which, internally uses a C++ Cypto library.

          J Offline
          J Offline
          JonB
          wrote on 13 Nov 2024, 15:36 last edited by
          #4

          @Pl45m4 said in Encryption/Decryption porting from .NET:

          Qt has .NET bindings... (urgh) :D

          It does, and there have been postings here for such projects.

          https://www.qt.io/blog/qt/.net-hosting-.net-code-in-a-qt-application
          https://gitlab.com/ddobrev/QtSharp
          https://github.com/qt-labs/qtdotnet
          https://forum.qt.io/topic/158127/how-do-i-create-real-c-bindings-for-qt6

          But whether any of them are up to the job I don't know.

          1 Reply Last reply
          0
          • T Offline
            T Offline
            Toto83
            wrote on 14 Nov 2024, 08:38 last edited by
            #5

            Thanks for yours hints. I've made several test but it was a bloodbath. For this moment I'll put this topic aside and I'll try to remove the constraint of the backward compatibility. This project is an evolution of present system and other constraints are already broken.
            Meanwhile I've found this class https://github.com/bricke/Qt-AES
            It works readly good.

            Thanks to all

            J 1 Reply Last reply 14 Nov 2024, 08:48
            0
            • T Toto83
              14 Nov 2024, 08:38

              Thanks for yours hints. I've made several test but it was a bloodbath. For this moment I'll put this topic aside and I'll try to remove the constraint of the backward compatibility. This project is an evolution of present system and other constraints are already broken.
              Meanwhile I've found this class https://github.com/bricke/Qt-AES
              It works readly good.

              Thanks to all

              J Offline
              J Offline
              JonB
              wrote on 14 Nov 2024, 08:48 last edited by
              #6

              @Toto83
              Yes, it will be much simpler if you can use new Qt/C++ encrypt/decrypt algorithms. Do you need RijndaelManaged, and more particularly Rfc2898DeriveBytes, in order to support decrypting data already encrypted with the latter algorithm? If not I would abandon that encryption method and use a new Qt/C++ one, greatly simplifying the conversion.

              1 Reply Last reply
              0

              1/6

              13 Nov 2024, 15:10

              • Login

              • Login or register to search.
              1 out of 6
              • First post
                1/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved