我一直在研究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)
在第5步中,Oracle客户端在AUTH_PASSWORD值的低16字节中放置了什么?
我发现的几乎所有文档都只关心获取其中包含的纯文本密码,而不关注这些第一个字节.我曾尝试查看JDBC驱动程序,但似乎即使是10g版本也会通过请求服务器恢复到较旧的方案(这恰好可以更好地理解)来避免此身份验证方案.一个优秀的C program演示了AUTH_PASSWORD的解密.
谁能指出我正确的方向?
最佳答案 我已经确定了明文密码之前的16个字节是随机生成的(对于好奇的,看看oran10.dll库导出的ztvo5pe函数 – 你会看到两次连续调用ztcen,第一个调用填充它在).
我最初发布这个问题是因为我正在编写一个小程序来连接Oracle数据库,而不使用Oracle的JDBC驱动程序.我发现数据库拒绝了我的32字节AUTH_PASSWORD.我认为它被拒绝了,因为我在前16个字节中放了一个不正确的值.我错了.看来这些对用户是否进行身份验证没有任何影响.
相反,事实证明数据库拒绝我的AUTH_PASSWORD,因为明文密码后面紧跟着尾随字节.我天真地用零填充缓冲区.它应该根据PKCS#7规范进行填充.