Git Product home page Git Product logo

Comments (25)

wmmihaa avatar wmmihaa commented on June 12, 2024 46

@davidathompson ...hope this can be of help

Helper class

public static class CipherHelper
    {
        // This constant is used to determine the keysize of the encryption algorithm in bits.
        // We divide this by 8 within the code below to get the equivalent number of bytes.
        private const int Keysize = 256;

        // This constant determines the number of iterations for the password bytes generation function.
        private const int DerivationIterations = 1000;

        public static string Encrypt(string plainText, string passPhrase)
        {
            // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
            // so that the same Salt and IV values can be used when decrypting.  
            var saltStringBytes = Generate256BitsOfRandomEntropy();
            var ivStringBytes = Generate256BitsOfRandomEntropy();
            var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
            {
                var keyBytes = password.GetBytes(Keysize / 8);
                var engine = new RijndaelEngine(256);
                var blockCipher = new CbcBlockCipher(engine);
                var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
                var keyParam = new KeyParameter(keyBytes);
                var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);

                cipher.Init(true, keyParamWithIV);
                var comparisonBytes = new byte[cipher.GetOutputSize(plainTextBytes.Length)];
                var length = cipher.ProcessBytes(plainTextBytes, comparisonBytes, 0);

                cipher.DoFinal(comparisonBytes, length);
                //                return Convert.ToBase64String(comparisonBytes);
                return Convert.ToBase64String(saltStringBytes.Concat(ivStringBytes).Concat(comparisonBytes).ToArray());
            }
        }

        public static string Decrypt(string cipherText, string passPhrase)
        {
            // Get the complete stream of bytes that represent:
            // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
            var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
            // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
            var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
            // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
            var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
            // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
            var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();

            using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
            {
                var keyBytes = password.GetBytes(Keysize / 8);
                var engine = new RijndaelEngine(256);
                var blockCipher = new CbcBlockCipher(engine);
                var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
                var keyParam = new KeyParameter(keyBytes);
                var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);

                cipher.Init(false, keyParamWithIV);
                var comparisonBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
                var length = cipher.ProcessBytes(cipherTextBytes, comparisonBytes, 0);

                cipher.DoFinal(comparisonBytes, length);
                //return Convert.ToBase64String(saltStringBytes.Concat(ivStringBytes).Concat(comparisonBytes).ToArray());

                var nullIndex = comparisonBytes.Length - 1;
                while (comparisonBytes[nullIndex] == (byte)0)
                    nullIndex--;
                comparisonBytes = comparisonBytes.Take(nullIndex + 1).ToArray();


                var result = Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length);

                return result;
            }
        }

        private static byte[] Generate256BitsOfRandomEntropy()
        {
            var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
            using (var rngCsp = new RNGCryptoServiceProvider())
            {
                // Fill the array with cryptographically secure random bytes.
                rngCsp.GetBytes(randomBytes);
            }
            return randomBytes;
        }
    }

Unit test

[Test]
        public async Task CipherHelper_ShouldWork()
        {
            try
            {
                var value = "Secret to encrypt";
                var passPhrase = "your pass phrase";
                var encryptedValue = CipherHelper.Encrypt(value, passPhrase);
                var decryptedValue = CipherHelper.Decrypt(encryptedValue, passPhrase);
                
                Assert.IsTrue(value == decryptedValue);
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
        }

from rijndael256.

suj87 avatar suj87 commented on June 12, 2024 11

@wmmihaa Thanks for this - seems to work flawlessly. For anyone wondering - it requires BouncyCastle.NetCore :)

from rijndael256.

niemyjski avatar niemyjski commented on June 12, 2024 8

+1

from rijndael256.

RajeshAKumar avatar RajeshAKumar commented on June 12, 2024 8

We have a desktop software using WPF and written a crypto library using RijndaelManaged using .NET FX 4.0 ~2010-2011 timeframe.
Now we are moving that code base to .NET 6, and discover this issue.
We are also Microsoft Partner and this is leaving us high and dry.

If MS supported RijndaelManaged with 256 bit blocksize, then it should have a upgrade route. We can definitely use the newer and ratified AES also, but what do we do with encrypted data at rest in files. We do have to support data/ config files from our older products and can not abandon that.
Right now the only working solution is to use BouncyCastle.NetCore.
When MS has 1000s of developers, how hard is it to support 256 bit blocksize giving us a native .NET solution instead of relying on a 3rd party library.
We plan to use it for "Reading old", and generate new files using new AES.
But do not like the concept no straightforward upgrade path.

I strongly vote for this to be added to .NET 6.

from rijndael256.

JasonPierce avatar JasonPierce commented on June 12, 2024 3

Reopening, since interest is spiking

from rijndael256.

ByronAP avatar ByronAP commented on June 12, 2024 1

.net core 2.0 and any example using a 256 block size will fail because you are trying to use AES which does not support that. This is block size not key size, a 256 key should work, a 256 block size will absolutely not work unless you write the actual rounds from scratch because the .net core team has emphatically refused to support Rijndael. You can try it by making a .net core console app and trying to decrypt anything that has been encrypted using Rijndael 256. It will fail as soon as you try and set that invalid block size. To further prove this remove the net45 section in the src, it should fail on all systems since it is AES (not tested but should).

from rijndael256.

JasonPierce avatar JasonPierce commented on June 12, 2024 1

@ByronAP can you provide an example illustrating how you're using a 256 block size with Rijndael256?

Rijndael256 currently supports:

  • 128-128
  • 192-128
  • 256-128

N-256 isn't something I set out to support when I created this lib, but if a significant number of users would like to see it, I'm not opposed to investigating it's implementation. Are you certain you want to use 256 block size? It hasn't had nearly as much attention as 128 block size (which means it could have weaknesses that have yet to be discovered).

from rijndael256.

jbaumbach avatar jbaumbach commented on June 12, 2024 1

Thanks @wmmihaa and @suj87 , totally works. We were dead in the water before!

from rijndael256.

JasonPierce avatar JasonPierce commented on June 12, 2024

What version of .NET Core are you using @ByronAP? Can you provide an example?

from rijndael256.

ByronAP avatar ByronAP commented on June 12, 2024

I'm sure it is not all that common in .net however some libs in php use it along with some other functions so not having it in c# creates an interoperability impediment. I personally wouldn't bother because you have to write the whole thing yourself or rip some code from bouncy castle to make it work for what is essentially an edge case.

from rijndael256.

JasonPierce avatar JasonPierce commented on June 12, 2024

Closing, since there doesn't appear to be a great interest in this feature. Will re-open if that changes.

from rijndael256.

ciacco85 avatar ciacco85 commented on June 12, 2024

https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp

I'm using this easy and nice implementation that use 256 block size, could you have a look at it?
it's native (only system.security) and super fast to test

from rijndael256.

Gabriel-Espinoza avatar Gabriel-Espinoza commented on June 12, 2024

I'm using the same as @ciacco85 but doesn't work on .net core cause it's block size is 256 D:

from rijndael256.

parabola949 avatar parabola949 commented on June 12, 2024

@Gabriel-Espinoza https://stackoverflow.com/a/51947250/773165

from rijndael256.

tedebus avatar tedebus commented on June 12, 2024

I'm very interested, too. I have a library based created on .Net Standard. Importing it on .Net Framwork all goes right but using it on .Net Core I have problems.

from rijndael256.

darrinjolson avatar darrinjolson commented on June 12, 2024

I have a similar issue, as well. I have data stored that is encrypted using an initialization vector that requires a block size of 256. I'm trying to find a way to decrypt these values in .NET Core and cannot use 256.

from rijndael256.

JasonPierce avatar JasonPierce commented on June 12, 2024

Unfortunately, as of .NET Core 3.1, RijndaelManaged still does not support block sizes greater than 128. Looking at the source code, you can see .NET Core throws an exception if you try to use 192 or 256: https://github.com/dotnet/corefx/blob/release/3.1/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RijndaelImplementation.cs#L37

cc: @ciacco85 , @Gabriel-Espinoza

from rijndael256.

ByronAP avatar ByronAP commented on June 12, 2024

they have made it quite clear over the years that it will never be supported since it is not an official implementation :-(

from rijndael256.

wmmihaa avatar wmmihaa commented on June 12, 2024

+1 @JasonPierce are you still working on this?

from rijndael256.

JasonPierce avatar JasonPierce commented on June 12, 2024

@wmmihaa I'm keeping on eye on it. Unfortunately, as of .NET Core 3, it still does not support this. We can hope that they do add support in the new .NET 5 that is currently in Preview 1. Perhaps we'll get support for it at that time, since it is currently supported in .NET Framework 🤞

from rijndael256.

sediinhesari avatar sediinhesari commented on June 12, 2024

I believe it is necessary to provide 256 blocksize encryption and decryption.
We have an old windows application that used 256 blocksize to encrypt passwords in the database.
Now we are developing a web application version.
the problem is we can not use that data in the web application which is developing with asp.net core 3

from rijndael256.

dericferreira avatar dericferreira commented on June 12, 2024

Hey,

If .NET Core 3.1 still does not support 256 initialization vector why documentation does not reflect that?

Look at this:

//RijndaelManaged
// Legal min key size = 128
// Legal max key size = 256
// Legal min block size = 128
// Legal max block size = 256

Anybody can't get the same result! Why does the documentation is not refleting the truth?

https://docs.microsoft.com/pt-br/dotnet/api/system.security.cryptography.symmetricalgorithm.legalkeysizes?view=netcore-3.1

from rijndael256.

davidathompson avatar davidathompson commented on June 12, 2024

Just discovered this, and it creates a huge block. I have to support decryption in .net core of values encrypted with .net framework using 256 bit. Arrrrgggg!!!

from rijndael256.

zutroy97 avatar zutroy97 commented on June 12, 2024

@wmmihaa Thank you! That is exactly what I needed. You saved me a ton of time.

from rijndael256.

viniciusvillas avatar viniciusvillas commented on June 12, 2024

@wmmihaa, thank you so much! Saved us a lot of time. Cheers! ❤️

from rijndael256.

Related Issues (12)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.