Странная ошибка при преобразовании из VB в C# TripleDESCryptoServiceProvider исключение Указанный ключ не является допустимым размером для этого алгоритма - PullRequest
0 голосов
/ 02 мая 2020

Я построил программу шифрования паролей в Visual Basic c и портирую ее на c# Весь код правильно преобразован, насколько я вижу, я отлаживал программу до того момента, когда ошибка выдается все размеры ключей в приложении VB и в приложении c# одинаковы, но версия c# вызывает исключение.

Необработанное исключение: System.Security.Cryptography.CryptographicException: указанный ключ недопустим размер для этого алгоритма.

единственное различие между ними заключается в объявлении оператора в классе для использования во время выполнения.

vb

Private Wrapper As New EncryptionWrapper(key:=0) 

однако: = 0 не работает в c#, поэтому я использовал: "" вместо этого я думаю, что это может быть проблемой, но я надеюсь, что это не так, потому что я не уверен, что обходной путь.

c#

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

ох, и брокер безопасности - это всего лишь объявление для TripleDESCryptoServiceProvider, например

private TripleDESCryptoServiceProvider SecurityBroker = new TripleDESCryptoServiceProvider(); 

Visual Basi c:

''' <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
}

больше полезной информации rmation:

усеченная функция ha sh в 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;
        }

в 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

1 Ответ

0 голосов
/ 02 мая 2020

Здесь происходит несколько забавных вещей на VB:

  1. VB позволяет передавать целочисленный литерал 0 в строковый параметр. Эквивалентом является не пустая строка в C#, а строковый литерал "0".

  2. Этот 'ReDim Preserve' легко преобразуется в Array.Resize.

  3. Для преобразования целочисленного деления VB (оператор '\') требуется сопровождающее приведение, чтобы обеспечить усеченный результат целочисленного типа (например, VB).

, т. Е.

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;
    }

}
...