0

We aspire to achieve encryption and decryption in a way that ensures the length of the encrypted result aligns with the length of the original data. How can this objective be accomplished in .NET code?

For example:

string chars = "abcdeABCDE12345"; int resLen = 6;

String to encrypt:: Hello Word!

Result: CE1b5h

13
  • Why do you want to do this? What do you hope to achieve? Many methods need some type of Initialization Vector, and block based methods would round up the size. If you need some special, uncommon, solution you should probably explain what it is you are doing. Commented Dec 19, 2023 at 8:53
  • There is already an answer here stackoverflow.com/questions/985830/… Commented Dec 19, 2023 at 8:55
  • @JonasH I want to encrypt data which have data length same as the length of input string ,Input string may contains characters, numeric or any special characters Commented Dec 19, 2023 at 8:59
  • Which length do you mean? That of the ciphertext itself, the (e.g. Base64) encoded ciphertext or the length including necessary extra data such as IV and authentication tag? If it's only about the former: Any stream cipher mode (like CFB from the answer, although this is probably not the best choice) generates a ciphertext with the plaintext size. Commented Dec 19, 2023 at 9:58
  • 1
    Note that traditional encryptions use bytes and not strings, so an encoding comes into play (which performs the string-to-byte conversion). Example: The string abcdef is UTF-8 encoded 6 bytes long, but the string abcd€f is 8 bytes long. Therefore, specifying a length without encoding is incomplete. You may be referring to format-preserving encryption. Commented Dec 19, 2023 at 10:19

1 Answer 1

0

It's possible with AES CFB mode.

Simple implementation:

    static byte[] Encrypt(string plainText, byte[] key, byte[] iv)
    {
        using var aes = Aes.Create();
        aes.Key = key;
        aes.IV = iv;
        aes.Mode = CipherMode.CFB;
        aes.Padding = PaddingMode.None;

        var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

        using var msEncrypt = new MemoryStream();
        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            using var swEncrypt = new StreamWriter(csEncrypt);
            swEncrypt.Write(plainText);
        }
        return msEncrypt.ToArray();
    }

    static byte[] Decrypt(byte[] cipherText, byte[] key, byte[] iv)
    {
        using var aes = Aes.Create();
        aes.Key = key;
        aes.IV = iv;
        aes.Mode = CipherMode.CFB;
        aes.Padding = PaddingMode.None;

        var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

        using var msDecrypt = new MemoryStream(cipherText);
        using var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
        using var msDecrypted = new MemoryStream();
        csDecrypt.CopyTo(msDecrypted);
        return msDecrypted.ToArray();
    }

Usage:

var original = "Secret secret string";

using var aes = Aes.Create();
aes.GenerateKey();
aes.GenerateIV();

var encrypted = Encrypt(original, aes.Key, aes.IV);
var decrypted = Decrypt(encrypted, aes.Key, aes.IV);

Note:

That solution encrypts and decrypts to bytes array, if your goal is to get a string you can convert it by Encoding.UTF8.GetString(bytes)

Sign up to request clarification or add additional context in comments.

5 Comments

If the input data is 'abcdef' and has a length of 6, it is possible to achieve that the encrypted data will also have the same length
using var srDecrypt = new StreamReader(csDecrypt); return Encoding.UTF8.GetBytes(srDecrypt.ReadToEnd()); is not correct, that will take the encrypted bytes as if they are valid UTF8 which they might not be. Also inefficient. Instead just do return msDecrypt.ToArray(); or just return the stream
You've thrown away the IV, so this won't work in the real world. In your example the encryption and decryption occur in the same run of the program so you keep the IV around, but in real life decryption occurs some unspecified time after encryption.
@PraveenKumar CFB mode allows you to get the same amount of bytes after encryption/decryption
@PresidentJamesK.Polk probably I don't understand you, but you just can store the IV somewhere as well as the Key. Because you will need them both for decryption. Another way is to generate the IV from the Key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.