我一直在研究 Oracle 针对 10g 数据库进行身份验证的机制。尽管它的文档比其 9i 版本少,但我仍然设法在各种网站和博客上找到了它的许多详细信息。然而,一件仍然是一个谜。在我提到缺少什么之前,让我用伪代码解释一下对协议的了解:
// CLIENT SIDE PSEUDO CODE
user = "SCOTT"
password = "TIGER"
password_hash = oracle_password_hash(user, password)
// 1. Client provides user name to server
send(user)
// 2. Server responds with its encrypted AUTH_SESSKEY,
// a randomly generated number associated with the current session
encrypted_server_AUTH_SESSKEY = receive_AUTH_SESSKEY() // 32 bytes
decrypted_server_AUTH_SESSKEY = aes_decrypt(
encrypted_input => encrypted_server_AUTH_SESSKEY,
decryption_key => password_hash
)
// 3. Client generates its own AUTH_SESSKEY for this session
unencrypted_client_AUTH_SESSKEY = generate_random_AUTH_SESSKEY() // 32 bytes
encrypted_client_AUTH_SESSKEY = aes_encrypt(
unencrypted_input => unencrypted_client_AUTH_SESSKEY,
encryption_key => password_hash
)
// 4. Client combines the two AUTH_SESSKEYs using a known Oracle-specific algorithm
combined_AUTH_SESSKEYs = oracle_combine(decrypted_server_AUTH_SESSKEY, unencrypted_client_AUTH_SESSKEY)
// 5. Client builds AUTH_PASSWORD
unencrypted_AUTH_PASSWORD = byte[32]
unencrypted_AUTH_PASSWORD[0 .. 16] = ??? // THIS IS THE PROBLEM
unencrypted_AUTH_PASSWORD[16 .. 16 + len(password)] = password
unencrypted_AUTH_PASSWORD[16 + len(password) .. ] = PKCS#7 padding
// 6. Client encrypts the AUTH_PASSWORD data using the combined AUTH_SESSKEYs as the encryption key
encrypted_AUTH_PASSWORD = aes_encrypt(
unencrypted_input => unencrypted_AUTH_PASSWORD,
encryption_key => combined_AUTH_SESSKEYs
)
// 7. Client transmits its encrypted AUTH_SESSKEY and AUTH_PASSWORD to server for verification
send(encrypted_client_AUTH_SESSKEY, encrypted_AUTH_PASSWORD)
Oracle 客户端在步骤 5 中将 AUTH_PASSWORD 值的低 16 个字节放入了什么?
我发现的几乎所有文档都只关心获取其中包含的纯文本密码,很少注意这些第一个字节。我曾尝试查看 JDBC 驱动程序,但似乎即使是 10g 版本也通过请求服务器恢复为旧方案(这恰好更好理解)来避免这种身份验证方案。一个优秀的C 程序演示了 AUTH_PASSWORD 的解密。
谁能指出我正确的方向?