简体   繁体   中英

Strange error when converting from VB to C# TripleDESCryptoServiceProvider exception Specified key is not a valid size for this algorithm

I built a password encryption program in visual basic and am porting it to c# all of the code is correctly converted as far as i can see ive debugged the program up to the point that the error is thrown all the key sizes are the same in the VB app and in the c# app yet the c# version throws the exception.

Unhandled Exception: System.Security.Cryptography.CryptographicException: Specified key is not a valid size for this algorithm.

the only difference between the two is the declaration of the statement in a class for use at runtime.

vb

Private Wrapper As New EncryptionWrapper(key:=0) 

however:=0 does not work in c# so i used:"" instead i think this may be the issue but i hope its not because im not sure the workaround.

c#

private EncryptionWrapper Wrapper = new EncryptionWrapper(Key:""); 

oh and security broker is just the declaration for the TripleDESCryptoServiceProvider like so

private TripleDESCryptoServiceProvider SecurityBroker = new TripleDESCryptoServiceProvider(); 

Visual Basic:

''' <summary>
''' Class initializer to initialize the encryption wrapper with a new encryption password.
''' </summary>
''' <param name="key">Encryption password string.</param>
Sub New(ByVal key As String)
    'Initialize the crypto provider.
    SecurityBroker.Key = TruncateHash(key, SecurityBroker.KeySize \ 8) ' 196 - 24 (runtime values)
    SecurityBroker.IV = TruncateHash("", SecurityBroker.BlockSize \ 8) ' 64 - 8 (runtime values)
End Sub

c#:

//Class constructor
public EncryptionWrapper(string Key)
{
    SecurityBroker.Key = TruncateHash(Key, SecurityBroker.KeySize / 8);  //196 - 24
    SecurityBroker.IV = TruncateHash("", SecurityBroker.BlockSize / 8);  //64 - 8
}

more useful information:

truncate hash function in c#

        public byte[] TruncateHash(string Key, int length)
        {
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            byte[] keyBytes = System.Text.Encoding.Unicode.GetBytes(Key);
            byte[] hash = sha1.ComputeHash(keyBytes);

            return (byte[])RedimPreserve(hash, hash.Length - 1);
        }

        //c# custom function to take place of ReDim from VB
        public static Array RedimPreserve(Array originArray, Int32 desiredSize)
        {
            System.Type t = originArray.GetType().GetElementType();
            Array newArray = Array.CreateInstance(t, desiredSize);
            Array.Copy(originArray, 0, newArray, 0, Math.Min(originArray.Length, desiredSize));
            return newArray;
        }

in vb

    ''' <summary>
    ''' Truncates the hash to remove extra characters from the beginning and end
    ''' </summary>
    ''' <param name="key">Hash key</param>
    ''' <param name="length">Hash length</param>
    ''' <returns>A truncated hash byte array</returns>
    Private Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte()
        Dim sha1 As New SHA1CryptoServiceProvider

        'Hash the key.
        Dim keyBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(key)
        Dim hash() As Byte = sha1.ComputeHash(keyBytes)

        'Truncate or pad the hash.
        ReDim Preserve hash(length - 1)
        Return hash
    End Function

A bit of funny VB stuff happening here:

  1. VB allows you to pass the integer literal 0 to a string parameter. The equivalent is not an empty string in C#, but the string literal "0".

  2. This 'ReDim Preserve' converts trivially to Array.Resize.

  3. The conversion of VB integer division (operator '\') needs an accompanying cast to ensure a truncated integer result (like VB).

ie,

using System;

internal class Test
{
    private EncryptionWrapper Wrapper = new EncryptionWrapper(key: "0");
}

internal class EncryptionWrapper
{

    public EncryptionWrapper(string key) // 196 - 24 (runtime values)
    {
        //Initialize the crypto provider.
        SecurityBroker.Key = TruncateHash(key, Convert.ToInt32(SecurityBroker.KeySize) / 8);
        SecurityBroker.IV = TruncateHash("", Convert.ToInt32(SecurityBroker.BlockSize) / 8); // 64 - 8 (runtime values)
    }

    private byte[] TruncateHash(string key, int length)
    {
        SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

        //Hash the key.
        byte[] keyBytes = System.Text.Encoding.Unicode.GetBytes(key);
        byte[] hash = sha1.ComputeHash(keyBytes);

        //Truncate or pad the hash.
        Array.Resize(ref hash, length);
        return hash;
    }

}

Removing the -1 in the resized array of the truncate hash function fixed the pro

public byte[] TruncateHash(string Key, int length)
        {
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            byte[] keyBytes = System.Text.Encoding.Unicode.GetBytes(Key);
            byte[] hash = sha1.ComputeHash(keyBytes);

            Array.Resize(ref hash, length);

            return hash;
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM