В случае, если мои комментарии были неясны (или не верны), вот небольшая инструкция SQL, которая сделает то, что вы ищете.Это работает на 12c - но не буду клясться, что будет работать со всеми параметрами безопасности.Если у вас есть S: part в sys.user$.spare4
, это, вероятно, должно работать.
with trial as
(SELECT name,
-- The 1st 20 bytes (40 characters) of the "S" part are the hashed password
substr(substr(spare4,3,60),1,40) hashed_pwd,
-- The last 10 bytes (20 characters) of the "S" part are the plaintext salt
substr(substr(spare4,3,60),-20) salt,
-- I want to know if the password for user MYUSERNAME is "MYPASSWORDGUESS"...
'MYPASSWORDGUESS' trial_password
from sys.user$
where name = 'MYUSERNAME' ),
hashit as (
-- This SELECT adds the salt to our trial password and hashes it.
select name,
trial_password,
hashed_pwd,
salt,
-- The "3" is for the SH1 algorithm
sys.dbms_crypto.hash(
utl_raw.cast_to_raw(trial_password) || cast (salt as raw(10) ),3)
hashed_salted_trial
from trial )
-- If the resulting hash matches what Oracle has stored in spare4, it is good.
SELECT name,
trial_password,
case when hashed_pwd = hashed_salted_trial
then 'Y' ELSE 'N' END password_match
from hashit
;
Обновите «MYUSERNAME» и «MYPASSWORDGUESS» по мере необходимости для вашей базы данных.
ОБНОВЛЕНИЕ
На основании моего исходного кода в C # естьЕсть ли эквивалентный способ сделать следующее в C #?sys.dbms_crypto.hash (utl_raw.cast_to_raw (trial_password) || cast (соль как raw (10)), 3)
utl_raw.cast_to_raw(trial_password)
делает то же самое, что и Encoding.ASCII.GetBytes(plainTextString)
в вашем посте.Цель каждого из них состоит в том, чтобы сделать предположение о пароле и преобразовать его в байт.
cast(salt as raw(10))
не имеет эквивалента в вашем сообщении.Подробнее об этом позже.
||
- это способ объединения RAW
значений в Oracle.Он служит для той же цели, что и AppendByteArrays
в вашем сообщении.
sys.dbms_crypto.hash(..., 3)
- это то, как вы генерируете 160-битный хэш SHA-1 в Oracle.Я думаю, это то, что algorithm.ComputeHash
делает в вашем посте.
Итак, единственное, чего вам не хватает в вашем коде, это эквивалент cast(salt as raw(10))
.
Как мы уже говорили, вы не можетесоздать свою собственную соль для этого.Вы должны использовать соль, закодированную в user$.spare4
.Это будут последние 20 символов части «S:» в этом поле.Это выглядит так: FA338B110F78548CCB44
.Каждые два символа образуют шестнадцатеричный БАЙТ, который дает вам один байт вашей соли.Итак, в моем примере 1-й байт соли (заданный "FA") равен 15 (для "F") x16 + 10 (для "A") = 250.
Это, надеюсь, логика достаточнодля вас, чтобы реализовать в C #.Однако в этом нет необходимости, поскольку входное значение для соли может поступать только из user$.spare4
в базе данных Oracle.Так как вы все равно решили перейти в Oracle, просто
SELECT cast(substr(substr(spare4,3,60),-20) as RAW) FROM user$
так же просто, как просто
SELECT spare4 FROM user$
и все остальное в C #.Вы также можете позволить Oracle делать то, что у него хорошо получается.