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 key is not a valid size for this algorithm. #5

Closed
ichoes opened this issue Mar 4, 2014 · 6 comments
Closed

Specified key is not a valid size for this algorithm. #5

ichoes opened this issue Mar 4, 2014 · 6 comments
Labels

Comments

@ichoes
Copy link
Collaborator

ichoes commented Mar 4, 2014

I occasionally get the following error "Specified key is not a valid size for this algorithm".
When it happens it occurs on the Transform method the key is getting 7 bytes instead of 8.

@sgbj
Copy link
Owner

sgbj commented Mar 4, 2014

Thanks for taking the time to report this issue. It's because of the GetBytes extension method:

public static byte[] GetBytes(this BigInteger number)
{
    return number.ToByteArray().Reverse().SkipWhile(b => b == 0).ToArray();
}

It skips any zeros it sees in the beginning of the array. I added some code to the Dukpt.Transform method to counteract this behavior and add them back in instead of making the extension method context-aware.

It should be fixed now. =)

@ichoes
Copy link
Collaborator Author

ichoes commented Mar 5, 2014

Tested the change and it works perfectly now.
Thank you for the fix.

@ichoes ichoes closed this as completed Mar 5, 2014
@ichoes
Copy link
Collaborator Author

ichoes commented Mar 29, 2014

Hi,
I will reopen the ticket because i am getting the same error.
this time i am getting 15 bytes instead of 16.
to Fix it i did the following

if (k.Length > 8)
{
     cipher.Key = new byte[Math.Max(0, 16 - k.Length)].Concat(key.GetBytes()).ToArray();
}
else
{
     cipher.Key = new byte[Math.Max(0, 8 - k.Length)].Concat(key.GetBytes()).ToArray();
}

let me know if this is an acceptable solution.
Thanks

@ichoes ichoes reopened this Mar 29, 2014
@ichoes
Copy link
Collaborator Author

ichoes commented Mar 29, 2014

I have a better solution,

   public static BigInteger Transform(string name, bool encrypt, BigInteger key, BigInteger message)
        {
            using (var cipher = SymmetricAlgorithm.Create(name))
            {
                var k = key.GetBytes();
//gets the next multiple of 8
                cipher.Key = new byte[Math.Max(0, GetNearestWholeMultiple(k.Length,8) - k.Length)].Concat(key.GetBytes()).ToArray();
                cipher.IV = new byte[8];
                cipher.Mode = CipherMode.CBC;
                cipher.Padding = PaddingMode.Zeros;
                using (var crypto = encrypt ? cipher.CreateEncryptor() : cipher.CreateDecryptor())
                {
                    var data = message.GetBytes();
                    return BigInt.FromBytes(crypto.TransformFinalBlock(data, 0, data.Length));
                }
            }
        }

//gets the next multiple of 8
//Works with both scenarios, getting 7 bytes instead of 8 and Works when expecting 16 bytes and getting 15.
        private static int GetNearestWholeMultiple(decimal input, int X)
        {
            var output = Math.Round(input / X);
            if (output == 0 && input > 0) output += 1;
            output *= X;

            return (int)output;
        }

@ichoes ichoes closed this as completed Mar 29, 2014
@sgbj
Copy link
Owner

sgbj commented Mar 29, 2014

Thank you ichoes for fixing this issue!

@easytomanage
Copy link

In order to support either TripleDES or AES, you can use cipher.BlockSize / 8 instead of the hardcoded 8. This is for Key, IV, and data lines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants