Поэтому я попытался проверить подпись rsa-ps, которая подписалась в golang с помощью php-библиотеки phpseclib v3. Проверка php продолжает приносить мне ошибку. Но что меня смущает, так это когда я пытаюсь подписать подпись в php и убедиться, что она работает как в golang, так и в php.
это код, который я использую для подписи и проверки подписи в golang
Подпишите подпись
rng := rand.Reader
rsa.SignPSS(rng, key, crypto.SHA256, digest, nil)
Подтвердить подпись
rsa.VerifyPSS(key, crypto.SHA256, digest, signature, nil)
и это код для проверки и подписи подписи в php
Подтвердить подпись
$key = RSA::loadPublicKey('the key');
$result = $key->withHash('sha256')->withMGFHash('sha256')->verify($message, $signature);
Подпишите подпись
$key = RSA::loadPrivateKey('the key');
$key = $private->withPadding(RSA::SIGNATURE_PSS);
$signature = $private->withHash('sha256')->withMGFHash('sha256')->sign($message);
ПРИМЕЧАНИЕ Значение подписи возвращается в зашифрованном формате base64, и я уже расшифровал значение перед проверкой подписи.
Кто-нибудь может объяснить, как это происходит? и что я должен сделать, чтобы он работал для обоих?






PSS позволяет указывать различные параметры (s. RFC8017, 9.1.1): дайджест, функцию генерации маски (на практике применяется MGF1 и можно указать только его дайджест) и длину соли.
Проверка с помощью PHP завершается неудачно, потому что, хотя вы явно указываете дайджесты (чтобы они были идентичными в обоих кодах), вы используете библиотечные значения по умолчанию для длины соли, которые отличаются. Следовательно, два кода несовместимы:
В вашем коде Go в вызове SignPSS() 5-й параметр указан как nil, поэтому saltLength() дает PSSSaltLengthAuto, в результате чего применяется максимально возможная длина соли.
Максимально возможная длина соли составляет signature length - digest output length - 2 в байтах (например, с длиной подписи/ключа 2048 бит и SHA256 в качестве дайджеста: 256 - 32 - 2 байт).
В коде PHP длина вывода дайджеста (32 байта для SHA256) используется по умолчанию для длины соли, с. здесь.
Следовательно, чтобы PHP-код мог проверить подпись кода Go, длина соли должна быть явно установлена на максимальный размер с помощью withSaltLength():
$key = RSA::load($pubKey);
$result = $key
->withHash('sha256') // default (in V3)
->withMGFHash('sha256') // default (in V3)
->withSaltLength(256 - 32 - 2) // Fix! Replace 256 with your signature / key length in bytes
->verify($message, $signature);
print($result ? 'valid signature' : 'invalid signature'); // valid signature
Для полноты: максимальная длина соли также может быть определена с помощью:
$key->getLength()/8 - $key->getHash()->getLengthInBytes() - 2
В качестве альтернативы длина вывода дайджеста (32 байта для SHA256), которая применяется по умолчанию в коде PHP, может использоваться как длина соли в коде Go:
var ops rsa.PSSOptions
ops.SaltLength = rsa.PSSSaltLengthEqualsHash
signature, err := rsa.SignPSS(rng, keyPkcs8, crypto.SHA256, digest, &ops)
На практике длина вывода дайджеста часто используется как длина соли.