【发布时间】:2018-10-11 13:45:32
【问题描述】:
我有一个 Oracle 数据库。我想在 C# 中加密传入的密码,并将其与存储在名为 sys.user$ 的内置 oracle 表中的值进行比较,特别是“spare4”列。
可以这样做吗?我试图加密密码,但它没有生成与 Oracle 数据库表中生成的值相同的输出,所以很明显我缺少 Oracle 应用的逻辑。有什么想法吗?
据我了解,前 40 个字符是散列密码,后 20 个字符是散列盐值。
从 Oracle 11g 开始,它使用 Salt(不知道 Oracle 是如何生成它的)并应用于密码,然后使用 SHA-1 对其进行哈希处理以生成 S: 根据以下博客 password hashes 的一部分备用值和Spare 4 tips
这是当前代码:
public static string GenerateSaltedSHA1(string plainTextString, int saltSize)
{
HashAlgorithm algorithm = new SHA1Managed();
var saltBytes = GenerateSalt(saltSize);
var plainTextBytes = Encoding.ASCII.GetBytes(plainTextString);
var plainTextWithSaltBytes = AppendByteArrays(plainTextBytes, saltBytes);
var saltedSHA1Bytes = algorithm.ComputeHash((byte[]) plainTextWithSaltBytes);
var saltedSHA1WithAppendedSaltBytes = AppendByteArrays(saltedSHA1Bytes, saltBytes);
return Convert.ToBase64String(saltedSHA1WithAppendedSaltBytes);
}
private static byte[] GenerateSalt(int saltSize)
{
var rng = new RNGCryptoServiceProvider();
var buff = new byte[saltSize];
rng.GetBytes(buff);
return buff;
}
private static byte[] AppendByteArrays(byte[] byteArray1, byte[] byteArray2)
{
var byteArrayResult =
new byte[byteArray1.Length + byteArray2.Length];
for (var i = 0; i < byteArray1.Length; i++)
byteArrayResult[i] = byteArray1[i];
for (var i = 0; i < byteArray2.Length; i++)
byteArrayResult[byteArray1.Length + i] = byteArray2[i];
return byteArrayResult;
}
我了解在 Oracle 中 DBMS_CRYPTO 中有一些函数,例如哈希,可用于根据特定类型创建哈希,例如密码上的 MD5、SHA-1 等。
如果有更好的方法,我愿意接受建议。
【问题讨论】:
-
我认为您不想应用新生成的盐值。您想应用来自
spare4的 same 盐值。 -
你是对的,但根据他们关于 Oracle 如何生成盐的文档/博客,这并不明显。
-
你不需要知道它是如何生成的。只需将其从备用 4 中拉出即可。 Spare4 中的盐是纯文本盐,而不是盐的哈希值。那没有任何意义。盐不是“秘密”。