Nano Hash - криптовалюты, майнинг, программирование

Код VB с использованием cryptverifysignature advapi32.dll работает в Vista SP2, а не в 64-разрядной версии Windows 10

Я пытался выяснить, почему элемент приложения, написанный и скомпилированный на VB6 на машине Vista SP2, отлично работает на этой машине, но не на 64-битной машине с Windows 10. Чтобы улучшить возможности отладки, я воспроизвел код ошибки в Excel VBA. Работает на компьютере с Vista, но не на компьютере с Windows 10.

Все вызовы CryptoAPI объявляются следующим образом:

Private Declare Function CryptVerifySignature _
Lib "advapi32.dll" _
    Alias "CryptVerifySignatureA" ( _
        ByVal hHash As Long, _
        pbSignature As Byte, _
        ByVal dwSigLen As Long, _
        ByVal hPubKey As Long, _
        ByVal sDescription As String, _
        ByVal dwFlags As Long _
            ) As Long

Часть, которая не работает на компьютере с Windows 10, выделена железнодорожными путями вверху и внизу следующим образом:

Private Function SignValidate(ByRef abData() As Byte, _
                        ByRef abSigned() As Byte, _
                        Optional bSigned As Boolean = True) As Long
Dim hHash As Long
Dim lngReturnValue As Long
Dim lngSigLen As Long
Dim abText() As Byte
Dim strTxt As String
Dim lngW As Long
Dim lngX As Long
Dim lngY As Long

Dim abHashVal() As Byte

SignValidate = -1
ReDim abText(UBound(abData))
abText = abData

'Create a hash object to sign/validate
lngReturnValue = CryptCreateHash(hCryptProv, CALG_SHA, 0, 0, hHash)
If lngReturnValue = 0 Then
    'Set_locale regionalSymbol
    Err.Raise Err.LastDllError, , "DLL error code shown above. Could not create a Hash Object (CryptCreateHash API)"
End If
'Hash the data
lngW = UBound(abText) + 1
lngReturnValue = CryptHashData(hHash, abText(0), lngW, 0)
If lngReturnValue = 0 Then
    'Set_locale regionalSymbol
    Err.Raise Err.LastDllError, , "DLL error code shown above. Could not calculate a Hash Value (CryptHashData API)"
End If

If bSigned Then
    'release old key pair handle
    If hKeyPair <> 0 Then CryptDestroyKey hKeyPair
    'get a handle to the signature key pair
    lngReturnValue = CryptGetUserKey(hCryptProv, AT_SIGNATURE, hKeyPair)
    If lngReturnValue = 0 Then
        'Set_locale regionalSymbol
        Err.Raise Err.LastDllError, , "DLL error code shown above. Could not obtain key pair"
    End If
    'Determine the size of the signature
    lngReturnValue = CryptSignHash(hHash, AT_SIGNATURE, 0, 0, vbNull, lngSigLength)
    If lngSigLength > 0 Then ReDim abSig(lngSigLength - 1)
    'Sign the hash object
    lngReturnValue = CryptSignHash(hHash, AT_SIGNATURE, 0, 0, abSig(0), lngSigLength)
    If lngReturnValue = 0 Then
        'Set_locale regionalSymbol
        Err.Raise Err.LastDllError, , "DLL error code shown above. Could not sign the hash"
    End If
    ' the signature is now available
    ' size returned array to signature length
    ReDim abSigned(UBound(abSig))
    ' return the signature to the calling procedure
    abSigned = abSig
    SignValidate = 0
Else
    lngSigLength = UBound(abSigned) + 1
    ReDim abSig(UBound(abSigned))
    abSig = abSigned ' load the Signature array

'========================================================
    'this is the line where the actual validation is done
    lngReturnValue = CryptVerifySignature(hHash, abSig(0), lngSigLength, hKeyPair, 0, 0)
'========================================================
    If lngReturnValue = 0 Then 'some error occurred
        SignValidate = Err.LastDllError
    Else
        SignValidate = 0
    End If
End If
End Function

Компьютер с Windows 10 не выполняет выделенный вызов CryptVerifySignature и возвращает ошибку Err.LastDllError, равную NTE_BAD_SIGNATURE. Машина Vista проверяет подпись штрафа.

Я провел дни, исследуя, что здесь может происходить. Все безрезультатно. Любые указатели с благодарностью получены


  • Машина Vista 64-битная? 21.06.2016
  • Возможно, вам потребуется использовать атрибуты условной компиляции. Если у вас 64-битная версия офиса, версия VBA больше не VBA6, это VBA7. Вызов API / функций немного отличается. См. Эту статью от MS. msdn.microsoft.com/en-us / библиотека / офис / 21.06.2016
  • Спасибо за ответы. Машина Vista 32-битная. Excel 2003 на компьютере с Vista, 32-разрядный Excel 2016 на компьютере с Windows 10. Я считаю, что строка, которая не работает в VBA, - это та же строка, которая не работает в скомпилированной программе VB6, где вызов CryptVerifySignature находится в настраиваемой DLL. 21.06.2016
  • 32-битные типы и 64-битные типы не эквивалентны. Вызов CryptVerifySignature не получает параметры ожидаемых размеров. 21.06.2016
  • @Ryan Я просмотрел ссылку и взял: «Использование 32-разрядной версии Office 2010 позволяет использовать решения, созданные в предыдущих версиях Microsoft Office, без изменений». как подтверждение того, что версия VBA не является проблемой. 21.06.2016
  • Проверьте свое предположение. Используйте: # Если VBA7, то MsgBox (я версия 7!), Если вы получите окно сообщения, которое сообщает вам, какая версия. Также эта информация есть в Application.VBE.Version. 21.06.2016
  • Вы смотрели на использование PtrSafe в своих объявлениях API? 21.06.2016
  • @dbugger Вы говорите, что мне нужно сделать какое-то преобразование для 64-битной машины? Можете ли вы указать мне на что-то, что подробно описывает практические последствия использования pbSignature As Byte в 64-битной системе, а не в 32-битной системе? Я считаю, что указатель и правильная длина получены из вызова CryptSignHash. Я подумал, раз уж он исходил из той же системы, все будет синхронно. Прошу простить меня за незнание этих вопросов, очень ценю вашу помощь. 21.06.2016
  • @ Джим Хьюитт: Да, PtrSafe не имеет значения. 21.06.2016
  • Я заметил одну вещь: вы используете lngSigLength, который не объявлен. Я вижу Dim lngSigLen As Long. 21.06.2016
  • @Ryan VBA версии 7.01. Возможно, мне следовало дать более полную цитату раньше. Перед ним был префикс . С введением новой 64-разрядной версии Microsoft Office 2010 в настоящее время разрабатывается новая версия Microsoft Visual Basic для приложений (VBA), известная как Microsoft Visual Basic для приложений 7.0 (VBA 7). выпущен для работы как с 32-битными, так и с 64-битными приложениями. Важно отметить, что изменения, описанные в этой статье, применимы только к 64-разрядной версии Microsoft Office 2010. Я пришел к выводу, что, поскольку у меня был 32-разрядный Excel, VBA 6 или 7 были одинаковыми для меня? 21.06.2016
  • @Jim Hewitt Извините, объявлено на уровне модуля. Спасибо, что указали на повторяющееся объявление. 21.06.2016
  • Не уверен, что я полностью понимаю эту функцию (CryptVerifySignature), но вам может потребоваться изменить возвращаемое значение с Long на LongPtr. 21.06.2016
  • @Ryan Из MSDN Return value:If the function succeeds, the return value is TRUE.If the function fails, the return value is FALSE. Наверное, должно быть bool. 21.06.2016

Ответы:


1

После долгих разочарований и бесплодных исследований я в конце концов обнаружил, в чем проблема. Попутно я обнаружил, что проблема возникла совсем в другой части кода. Я также обнаружил, что проблема проявляется и в 32-битной Windows 10, а не в 64-битной.

Неправильно заполненный аргумент dwflags для более раннего вызова CryptImportKey, похоже, не помешал успешному вызову CryptVerifySignature в 32-битной Vista, даже несмотря на то, что вызов CryptImportKey при расследовании потерпел неудачу. После того, как аргумент dwflags CryptImportKey был исправлен на CRYPT_EXPORTABLE или CRYPT_NO_SALT, он был успешным, и последующий вызов CryptVerifySignature был успешным во всех альтернативных комбинациях операционной системы и номеров битов, которые я смог проверить.

Приносим свои извинения и благодарность в равной степени всем, кто пытался помочь в этом вопросе. До следующего раза.

07.05.2017

2

ИЗМЕНИТЬ - Я не вижу ничего плохого в вашем объявлении или звонке

Единственная альтернатива, которую я видел, - это изменить указатель байта, который будет объявлен как ByVal pSignature Long, а затем вызвать его с помощью varPtr(abSig(0)

Но ваш код выглядит нормально - я озадачен


Ваше объявление не соответствует заявлению Microsoft API. Не уверен, что это задумано, потому что подпись - это байтовый указатель.

Согласно документам

LPBYTE, BYTE  will be : *   ByRef Byte

Измените это (по умолчанию аргументы передаются ByVal)

pbSignature As Byte

К этому

ByRef pbSignature As Byte
22.06.2016
  • Спасибо за это. Я понял, что по умолчанию для VB6 (где, кажется, проявляется исходная проблема) было ByRef, но я думаю, что нет ничего плохого в том, чтобы быть явным, поэтому я сделаю все объявления явными и посмотрю, что произойдет. 26.06.2016
  • Просто изменил все объявления по умолчанию на ByRef, и ошибка точно такая же, как и раньше. 26.06.2016
  • Только pSignature должен быть ByRef - это единственный указатель. Я вижу, вы передаете первый элемент массива байтов - я отредактирую свой ответ выше для другого предложения вызова 26.06.2016
  • Во избежание сомнений, объявление теперь выглядит следующим образом: Private Declare Function CryptVerifySignature Lib advapi32.dll Псевдоним CryptVerifySignatureA (ByVal hHash As Long, ByRef pbSignature As Byte, ByVal dwSigLen As Long, ByVal hPubKey As Long, ByVal sDescription Ascription Ascription Долго) до тех пор, пока 26.06.2016
  • Пытался объявить как ByVal pSignature Long, а затем вызвать с помощью varPtr (abSig (0)), но все еще ошибка NTE_BAD_SIGNATURE. 27.06.2016
  • Ваш проект VB6 - это exe или компонент ActiveX? 27.06.2016
  • Можете ли вы проверить ярлык программы, чтобы увидеть, проверено ли что-нибудь на предмет совместимости? 27.06.2016
  • Это exe. Настройки режима совместимости не применяются. На этом этапе я был бы счастлив проигнорировать свой пример в пользу примера CryptVerifySignature VB, который, как известно, работает в 64-битной системе Windows 10. 27.06.2016
  • Можете ли вы загрузить и попробовать zip внутри zip - он расширяется до файла excel с демонстрационным примером - он не использует CryptVerifySignature, но объявляет другие функции с байтовыми указателями (с использованием ByVal bptr Long и VarPtr). Протестируйте демонстрацию в Excel в 64-разрядной версии Windows 10 и сообщите мне, работает ли она (должна) vbforums.com/ 27.06.2016
  • Но то же самое касается всего моего кода, кроме бита CryptVerifySignature. Так что я не собираюсь дальше определять проблему. 09.07.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..