Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specified initialization vector (IV) does not match the block size for this algorithm using TripleDesImplementation in asp.net core #27572

Closed
blowdart opened this issue Oct 8, 2018 · 14 comments
Labels
area-System.Security question Answer questions and provide assistance, not an issue with source code or documentation.
Milestone

Comments

@blowdart
Copy link
Contributor

blowdart commented Oct 8, 2018

From @Ashvini2004 on October 8, 2018 9:55

Hi
We have normal asp.net website where we used encryption/decryption of passwords using TripleDesImplementation algorithm.Now we are converting our site to asp.net core and just moved old encrypted passwords in new database user table. To login users in new site we need to decrypt old passwords so used same decrypt method which we were using earlier TripleDesImplementation algorithm but throwing exception as below,

Specified initialization vector (IV) does not match the block size for this algorithm.
Parameter name: rgbIV

At line

CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateDecryptor(KEY_192, IV_192), CryptoStreamMode.Read);

It's still working in our old site.

The encrypt and decryption code is as below:

public static string Encrypt(string p_szStrValue)
{
    string vszEncryptedString = string.Empty;

     private static byte[] KEY_192 = { XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX };
     private static byte[] IV_192 =  { XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX };

    if (!p_szStrValue.Trim().Equals(string.Empty))
    {
        TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateEncryptor(KEY_192, IV_192), CryptoStreamMode.Write);
        StreamWriter sw = new StreamWriter(cs);
        sw.Write(p_szStrValue);
        sw.Flush();
        cs.FlushFinalBlock();
        ms.Flush();
        vszEncryptedString = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
    }
    return vszEncryptedString;
}

public static string Decrypt(string p_szStrValue)
{
    string vszDecryptedString = string.Empty;
    if (!p_szStrValue.Trim().Equals(string.Empty))
    {
        try
        {
            TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
            byte[] v_Buffer = Convert.FromBase64String(p_szStrValue);
            MemoryStream ms = new MemoryStream(v_Buffer);
            CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateDecryptor(KEY_192, IV_192), CryptoStreamMode.Read);
            StreamReader sr = new StreamReader(cs);
            vszDecryptedString = sr.ReadToEnd();
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }
    return vszDecryptedString;
}

Copied from original issue: dotnet/aspnetcore#3596

@blowdart
Copy link
Contributor Author

blowdart commented Oct 8, 2018

From @Tratcher on October 8, 2018 15:1

@HaoK @blowdart

@blowdart
Copy link
Contributor Author

blowdart commented Oct 8, 2018

@Ashvini2004 I have deleted the key information you provided, on the assumption that might be your "live" encryption key and IV. If you can confirm that those are sample keys and IVs you can add them back, otherwise you have done something rather bad from a security POV and need to examine how to change your encryption keys ASAP.

@blowdart
Copy link
Contributor Author

blowdart commented Oct 8, 2018

Also as this isn't an ASP.NET issue, I'm moving this to corefx

@vcsjones
Copy link
Member

vcsjones commented Oct 8, 2018

3DES has a 64-bit block size, so the IV should be 8 bytes, not 24. I'm surprised this ever worked in .NET Framework.

I would assume then that perhaps .NET Framework is truncating the IV, or only using certain range of the bytes.

@vcsjones
Copy link
Member

vcsjones commented Oct 8, 2018

So it turns out the .NET Framework allows IVs greater than 64 bits and truncates them.

https://referencesource.microsoft.com/#mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs,101

// We truncate IV's that are longer than the block size to 8 bytes : this is
// done to maintain backward compatibility with the behavior shipped in V1.x.
// The call to set the IV in CryptoAPI will ignore any bytes after the first 8
// bytes. We'll still reject IV's that are shorter than the block size though.

So you should simply change your IV to only the first 8 bytes.

@vcsjones
Copy link
Member

vcsjones commented Oct 8, 2018

So, as an example:

private static byte[] IV_192 =  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 };

would become:

// Rename field if desired.
private static byte[] IV_192 =  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

@vcsjones
Copy link
Member

vcsjones commented Oct 8, 2018

@bartonjs is this a compat change we want to make, or perhaps we can improve documentation somewhere instead?

@bartonjs
Copy link
Member

bartonjs commented Oct 8, 2018

That compatibility seems to be in AesCryptoServiceProvider directly. AesCng (which for some reason isn't on referencesource) doesn't seem to have that same behavior... it's strict.

So I'd say, barring a copiousness of dupes/+1s/"me too"s, that CoreFX should guide people to the correct behavior and we should doc the difference. (Want to put up a docs PR? 😄)

@vcsjones
Copy link
Member

vcsjones commented Oct 8, 2018

Ah, I didn't even look at AES - the original issue is for 3DES, though since both were based on CAPI it makes sense they both behave the same.

Want to put up a docs PR?

Sure.

@bartonjs
Copy link
Member

bartonjs commented Oct 8, 2018

::mutter:: s/Aes/TripleDES/g

"That compatibility seems to be in TripleDESCryptoServiceProvider directly. TripleDESCng (which for some reason isn't on referencesource) doesn't seem to have that same behavior... it's strict."

@Ashvini2004
Copy link

Ashvini2004 commented Oct 9, 2018

@Ashvini2004 I have deleted the key information you provided, on the assumption that might be your "live" encryption key and IV. If you can confirm that those are sample keys and IVs you can add them back, otherwise you have done something rather bad from a security POV and need to examine how to change your encryption keys ASAP.

Thanks blowdart for deleting it.
I was not aware about this.

Can you please tell how we can change now these keys. If i'll change these keys then existing password decryption will not work right?
So can you please suggest what can be done now for maintaining security.

@Ashvini2004
Copy link

Thanks vcsjones.
I changed IV to 8 bytes and it's working now.

@vcsjones
Copy link
Member

vcsjones commented Oct 9, 2018

Can you please tell how we can change now these keys. If i'll change these keys then existing password decryption will not work right?

You will need to generate a new key and re-encrypt everything.

@vcsjones
Copy link
Member

@Ashvini2004 There's an issue at https://github.com/dotnet/docs/issues/8184 to get the documentation updated for the behavior you are seeing. Given that, does it seem reasonable that this issue can be closed?

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Security question Answer questions and provide assistance, not an issue with source code or documentation.
Projects
None yet
Development

No branches or pull requests

6 participants