Хэширование, CryptGetHashParam

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Хэширование, CryptGetHashParam

Сообщение Eugenio » 28.03.2007 (Ср) 13:41

В рез-те выполнения вот этого кода получаю из функции CryptGetHashParam в переданый массив одни нули. Не могу понять!
Причем, что интересно:
при выполнении функции CryptGetHashParam с параметром HP_HASHSIZE получаем в параметре pdwDataLen значение 4,
а при выполнении этой функции с параметром HP_HASHVAL получаем в параметре pdwDataLen значение 16
Код: Выделить всё

Private Const HP_HASHSIZE = &H4
'The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to the hash object earlier through the CryptHashData
Private Const HP_HASHVAL = &H2

    '
Private Declare Function CryptAcquireContext Lib "advapi32.dll" _
              Alias "CryptAcquireContextA" (ByRef phProv As Long, _
              ByVal pszContainer As String, ByVal pszProvider As String, _
              ByVal dwProvType As Long, ByVal dwFlags As Long) As Long
             
Private Declare Function CryptCreateHash Lib "advapi32.dll" _
              (ByVal hProv As Long, ByVal algid As Long, _
              ByVal hKey As Long, ByVal dwFlags As Long, _
              ByRef phHash As Long) As Long

Private Declare Function CryptHashData Lib "advapi32.dll" _
              (ByVal hHash As Long, pbData As Any, _
              ByVal dwDataLen As Long, ByVal dwFlags As Long) As Long
    '
Public Declare Function CryptGetHashParam Lib "advapi32.dll" _
  (ByVal hHash As Long, ByVal dwParam As Long, _
  pbData As Any, pdwDataLen As Long, _
  ByVal dwFlags As Long) As Long
 
Private Declare Function CryptDestroyHash Lib "advapi32.dll" _
              (ByVal hHash As Long) As Long
             
Private Declare Function CryptReleaseContext Lib "advapi32.dll" _
            (ByVal hProv As Long, _
            ByVal dwFlags As Long) As Long

Public Function GetStringHashValue(strDATA As String, HashValue() As Byte) As Boolean
    Dim blnResult As Boolean
    Const ERR_SOURCE As String = "U-Soft.HashModule.GetHashValue"
    Dim lngProvider As Long, lngHash As Long
    Dim lngDataLength As Long
   
    ' Aquire context to the microsoft default CSP
    blnResult = CBool(CryptAcquireContext(lngProvider, vbNullString, _
        MS_DEFAULT_PROVIDER, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
    If Not blnResult Then
        Err.Raise vbObjectError + 1, _
                    ERR_SOURCE, _
                    ERROR_AQUIRING_CONTEXT
        Exit Function
    End If
   
    blnResult = CBool(CryptCreateHash(lngProvider, CALG_MD5, 0, 0, lngHash))
    If Not blnResult Then
        Err.Raise vbObjectError + 2, ERR_SOURCE, ERROR_CREATING_HASH
        Exit Function
    End If

    lngDataLength = Len(strDATA)
    blnResult = CBool(CryptHashData(lngHash, ByVal strDATA, lngDataLength, 0))
    If Not blnResult Then
        Err.Raise vbObjectError + 3, ERR_SOURCE, ERROR_CREATING_HASH_DATA
        Exit Function
    End If
    lngDataLength = 0
    blnResult = CBool(CryptGetHashParam(lngHash, HP_HASHSIZE, ByVal 0&, lngDataLength, 0&))
    If Not blnResult Then
        Err.Raise vbObjectError + 4, ERR_SOURCE, ERROR_GETTING_RESULTS + " (HP_HASHSIZE)"
        Exit Function
    End If
    ReDim HashValue(0 To lngDataLength - 1)
     blnResult = CBool(CryptGetHashParam(lngHash, HP_HASHVAL, ByVal HashValue(0), lngDataLength, 0&))
     If Not blnResult Then
        Err.Raise vbObjectError + 4, ERR_SOURCE, ERROR_GETTING_RESULTS + " (HP_HASHVAL)"
        Exit Function
    End If
   
    Call CryptDestroyHash(lngHash)
    Call CryptReleaseContext(lngHash, 0)
   
    GetStringHashValue = blnResult 'left$(strDATA, lngDataLength)

End Function
Последний раз редактировалось Eugenio 28.03.2007 (Ср) 14:29, всего редактировалось 1 раз.
Есть ли у меня вопрос? У меня всегда есть вопрос

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 28.03.2007 (Ср) 14:04

Сдается мне, что надо было объявлять так:

Код: Выделить всё
Public Declare Function CryptGetHashParam Lib "advapi32.dll" _
  (ByVal hHash As Long, ByVal dwParam As Long, _
  ByVal pbData As Long, pdwDataLen As Long, _
  ByVal dwFlags As Long) As Long


и вызывать соответственно так:

Код: Выделить всё
blnResult = CBool(CryptGetHashParam(lngHash, HP_HASHVAL,  HashValue(0), lngDataLength, 0&))
Последний раз редактировалось Viper 28.03.2007 (Ср) 15:20, всего редактировалось 1 раз.
Весь мир матрица, а мы в нем потоки байтов!

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 28.03.2007 (Ср) 14:50

!Viper! писал(а):Сдается мне, что надо было объявлять так:

Код: Выделить всё
Public Declare Function CryptGetHashParam Lib "advapi32.dll" _
  (ByVal hHash As Long, ByVal dwParam As Long, _
  pbData As Long, pdwDataLen As Long, _
  ByVal dwFlags As Long) As Long


и вызывать соответственно так:

Код: Выделить всё
blnResult = CBool(CryptGetHashParam(lngHash, HP_HASHVAL,  HashValue(0), lngDataLength, 0&))

Ну, по идее указатель - это long, но Any заменяет его.
А если ставить Long, это вызывает
ByRef argument type mismatch
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 28.03.2007 (Ср) 14:58

Почему с длиной так выходит, вот чего не могу понять
Есть ли у меня вопрос? У меня всегда есть вопрос

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 28.03.2007 (Ср) 15:18

Нды... так ты в него массив Variant пытаешься спровадить? Собственно даже если так, то для своего варианта объявляения вызывай функцию так:

Код: Выделить всё
blnResult = CBool(CryptGetHashParam(lngHash, HP_HASHVAL,  VarPtr(HashValue(0)), lngDataLength, 0&))


А лучше объяви массив нужного типа, объяви функцию соответственно и вызывай как я советовал.
Весь мир матрица, а мы в нем потоки байтов!

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 29.03.2007 (Чт) 6:41

!Viper! писал(а):Нды... так ты в него массив Variant пытаешься спровадить? Собственно даже если так, то для своего варианта объявляения вызывай функцию так:

Код: Выделить всё
blnResult = CBool(CryptGetHashParam(lngHash, HP_HASHVAL,  VarPtr(HashValue(0)), lngDataLength, 0&))


А лучше объяви массив нужного типа, объяви функцию соответственно и вызывай как я советовал.

Где тут Variant? Массив объявлен as byte.
И неясно, почему размер возвращается некорректно.
Есть ли у меня вопрос? У меня всегда есть вопрос

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 29.03.2007 (Чт) 6:59

действительно... Byte ... извиняюсь, просмотрел. Тем более способ вызова должен быть как у меня
Весь мир матрица, а мы в нем потоки байтов!

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 29.03.2007 (Чт) 7:16

Если объявить параметр as Long и передавать VarPtr, возникает ошибка 234 (More data available), какого бы размера массив ни был.
Я его ради интересу раздвинул до 1000 байт - всё едино!


Всё, разобрался. Использовал статейку, в которой некорректно описано получение размера буфера.
Есть ли у меня вопрос? У меня всегда есть вопрос

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 29.03.2007 (Чт) 7:31

Надеюсь при вызове с VarPtr аргумент объявлен как ByVal ... As Long?

ADD: нет бы MSDN использовать
Весь мир матрица, а мы в нем потоки байтов!

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 29.03.2007 (Чт) 11:09

Ты вообще-то советовал его ByRef объявить:-)
Я, наудачу, проделал всё так, как ты советовал.
А во-вторых, если передать HashValue(0) по ссылке, то в библиотечную функцию прилетит именно то, что нужно: указатель на первый элемент массива. Что я и сделал с самого начала.
Причина траблов была не в передаче параметров.

В MSDN примеры на Basic по шифрованию.
Вот я и полез в И-нет.
Есть ли у меня вопрос? У меня всегда есть вопрос

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 29.03.2007 (Чт) 11:13

Вообще то у меня ByVal, ну да ладно... суть похоже действительно был не в этом. Примеры в MSDN стоит смотреть на C, а не на VB, уоих там по API функциям и нет вовсе
Весь мир матрица, а мы в нем потоки байтов!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 61

    TopList