Расширение API не позволяет авторизоваться из-за неправильного hmac или hkdfPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Расширение API не позволяет авторизоваться из-за неправильного hmac или hkdf

Сообщение Anonymous »

Я пытаюсь воспроизвести процесс входа в систему в этом репозитории Python. В функции входа в систему есть 4 шага, и у меня возникли проблемы со вторым шагом. Я правильно прохожу первый шаг и извлекаю всю необходимую информацию из «ChallengeParameters», однако когда я пытаюсь выполнить второй шаг, я получаю http-ответ ниже. Я на 100 процентов уверен, что введенный мной пароль правильный, и все значения из «ChallengeParameters» кажутся верными. Я чувствую, что проблема в том, как рассчитывается подпись, поскольку вычисления довольно сложны, и я чувствую, что неправильно конвертирую их из Python.
{"__type":"NotAuthorizedException","message":"Incorrect username or password."}
Когда я очищаю веб-JS, я получаю: (и то, что я передаю в аутентификацию)
deviceKey = "-d4yTUB0o"
devicePassword = "us-east-1_c75a763a-304d-46f4-8b56-b72cb0101dac"
randomPasswordKey = "Nk/v/8FbJPo16AxlzUN3BFVw4NoMIRkslKpcQQUsh76eWezJwUE55g=="

Соответствующий код по ссылке выше находится в файлах cognito/srp.py и cognito/auth.py. Я не рекомендую пытаться воспроизвести это, я думаю, моя проблема в непонимании CryptoKit и конвертации кода Python. Если вы хотите попытаться воспроизвести это, вам нужно будет создать учетную запись Extend VCC. Также вам необходимо извлечь 3 переменные, как показано в файле readme по ссылке.
Чтобы вызвать код, вы можете просто сделать:
let authParams = AuthParams(username: email, password: password, deviceKey: deviceKey, devicePassword: randomPasswordKey, deviceGroupKey: deviceGroupKey)
let cognito = Cognito(auth: authParams)

Task {
do {
let accessToken = try await cognito.authenticate()
} catch {
print("Err")
}
}

srp-файл
import Foundation
import CryptoKit
import BigInt

class SRPAuthentication {
private let auth: AuthParams
private let N_HEX = """
FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF
"""
private let G_HEX = "2"
private let INFO_BITS = "Caldera Derived Key"
private let N: BigInt
private let g: BigInt
private let a: BigInt
private let A: BigInt

init(auth: AuthParams) {
self.auth = auth
self.N = BigInt(N_HEX, radix: 16) ?? BigInt(0)
self.g = BigInt(G_HEX, radix: 16) ?? BigInt(0)
self.a = SRPAuthentication.generateRandomSmallA(N: self.N)
self.A = SRPAuthentication.calculateA(g: self.g, a: self.a, N: self.N)
}

func getAuthParams() -> [String: String] {
return ["USERNAME": auth.username, "SRP_A": self.A.serialize().hexEncodedString()]
}

func passwordVerifierChallenge(challengeParams: [String: Any]) -> [String: String] {
guard let challengeParameters = challengeParams["ChallengeParameters"] as? [String: Any] else {
print("Error: Missing or invalid 'ChallengeParameters'")
return [:]
}

guard let username = challengeParameters["USERNAME"] as? String,
let userId = challengeParameters["USER_ID_FOR_SRP"] as? String,
let saltHex = challengeParameters["SALT"] as? String,
let srpBHex = challengeParameters["SRP_B"] as? String,
let secretBlockB64 = challengeParameters["SECRET_BLOCK"] as? String,
let bigB = BigInt(srpBHex, radix: 16),
let salt = BigInt(saltHex, radix: 16),
let secretBlock = Data(base64Encoded: secretBlockB64) else {
print("Error: Missing or invalid parameters in challengeParameters")
return [:]
}

let hkdf = self.getPasswordAuthenticationKey(
poolName: "pN4CuZHEc",
userId: userId,
password: self.auth.password,
bigB: bigB,
salt: salt
)

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(identifier: "UTC")
dateFormatter.dateFormat = "EEE MMM dd HH:mm:ss 'UTC' yyyy"
let timestamp = dateFormatter.string(from: Date())

// Create message
var message = "pN4CuZHEc\(userId)".data(using: .utf8)!
message.append(secretBlock)
message.append(timestamp.data(using: .utf8)!)

// Calculate HMAC signature
let hmac = HMAC.authenticationCode(for: message, using: SymmetricKey(data: hkdf))
let signature = Data(hmac).base64EncodedString()

return [
"TIMESTAMP": timestamp,
"USERNAME": username,
"PASSWORD_CLAIM_SECRET_BLOCK": secretBlockB64,
"PASSWORD_CLAIM_SIGNATURE": signature,
"DEVICE_KEY": self.auth.deviceKey
]
}

private func getPasswordAuthenticationKey(
poolName: String,
userId: String,
password: String,
bigB: BigInt,
salt: BigInt
) -> Data {
// Calculate U value
let u = calculateU(A: self.A, B: bigB)

// Calculate X value
let userPass = "\(poolName)\(userId):\(password)"
let userPassHash = SHA256.hash(data: userPass.data(using: .utf8)!).hexEncodedString()
let xHex = padHex(longToHex(salt)) + userPassHash
let x = hexToLong(xHex)

// Calculate S value
let gPowXN = g.power(x, modulus: N)
let intVal1 = (bigB - (self.k() * gPowXN)) % N
let intVal2 = (self.a + (u * x)) % (N - 1)
let s = intVal1.power(intVal2, modulus: N)

// Compute HKDF
return computeHKDF(inputKeyMaterial: padHex(longToHex(s)), salt: padHex(longToHex(u)))
}

private func calculateU(A: BigInt, B: BigInt) -> BigInt {
let uHex = padHex(longToHex(A)) + padHex(longToHex(B))
return hexToLong(SHA256.hash(data: uHex.data(using: .utf8)!).hexEncodedString())
}

private func computeHKDF(inputKeyMaterial: String, salt: String) -> Data {
let ikm = Data(hex: inputKeyMaterial)
let saltData = Data(hex: salt)
let prk = HMAC.authenticationCode(for: ikm, using: SymmetricKey(data: saltData))
let infoBits = (INFO_BITS + "\u{01}").data(using: .utf8)!
return Data(HMAC.authenticationCode(for: infoBits, using: SymmetricKey(data: prk))).prefix(16)
}

private func k() -> BigInt {
let kHex = "00\(N_HEX)0\(G_HEX)"
return BigInt(sha256Hex(kHex), radix: 16) ?? BigInt(0)
}

static func generateRandomSmallA(N: BigInt) -> BigInt {
guard N > 1 else {
fatalError("N must be greater than 1 for random generation.")
}
return BigInt(Int.random(in: 1.. BigInt {
return g.power(a, modulus: N)
}
}

struct AuthParams {
let username: String
let password: String
let deviceKey: String
let devicePassword: String
let deviceGroupKey: String
}

extension Data {
func hexEncodedString() -> String {
return map { String(format: "%02x", $0) }.joined()
}
}

extension Sequence where Element == UInt8 {
func hexEncodedString() -> String {
return map { String(format: "%02x", $0) }.joined()
}
}

enum CognitoError: Error {
case invalidURL
case requestFailed
case unexpectedChallenge(challengeName: String)
}

func sha256Hex(_ input: String) -> String {
let data = input.data(using: .utf8)!
let digest = SHA256.hash(data: data)
return digest.map { String(format: "%02x", $0) }.joined()
}

extension Data {
init(hex: String) {
self.init(Array(hex: hex))
}
}

extension Array where Element == UInt8 {
init(hex: String) {
self = hex.compactMap { UInt8(String($0), radix: 16) }
}
}

func hexToLong(_ hex: String) -> BigInt {
return BigInt(hex, radix: 16) ?? BigInt(0)
}

func longToHex(_ number: BigInt) -> String {
return String(number, radix: 16)
}

func padHex(_ hex: String) -> String {
return hex.count % 2 == 0 ? hex : "0" + hex
}

известный файл
import Foundation
import CryptoKit
import BigInt

class Cognito {
private let srp: SRPAuthentication
private var accessToken: String = ""
private var refreshToken: String = ""
private var expiry: Date = Date()
private let session: URLSession
private let lock = NSLock()

init(auth: AuthParams) {
self.srp = SRPAuthentication(auth: auth)
self.session = URLSession(configuration: .default)
}

func authenticate() async throws -> String {
let userChallenge = try await userSRPAuth()

if let challengeName = userChallenge["ChallengeName"] as? String, challengeName == "PASSWORD_VERIFIER" {
print(challengeName)
} else {
print("user challenge")
throw CognitoError.unexpectedChallenge(challengeName: "VERIFIER Err")
}

let deviceAuth = try await userPasswordVerifier(challengeParams: userChallenge)

if let challengeName = deviceAuth["ChallengeName"] as? String, challengeName == "DEVICE_SRP_AUTH" {
print(challengeName)
} else {
print("device auth")
throw CognitoError.unexpectedChallenge(challengeName: "SRP_AUTH Err")
}

// TODO step 3 and 4

return "" // return access token
}

private func userSRPAuth() async throws -> [String: Any] {
return try await makeRequest(
target: "AWSCognitoIdentityProviderService.InitiateAuth",
body: [
"AuthFlow": "USER_SRP_AUTH",
"ClientId": "79k2g0t0ujq2tfchb23d5j6htk",
"AuthParameters": srp.getAuthParams(),
"ClientMetadata": [:]
]
)
}

private func userPasswordVerifier(challengeParams: [String: Any]) async throws -> [String: Any] {

let challenge_responses = srp.passwordVerifierChallenge(challengeParams: challengeParams)

return try await makeRequest(
target: "AWSCognitoIdentityProviderService.RespondToAuthChallenge",
body: [
"ChallengeName": "PASSWORD_VERIFIER",
"ClientId": "79k2g0t0ujq2tfchb23d5j6htk",
"ChallengeResponses": challenge_responses,
"ClientMetadata": [:]
]
)
}

func makeRequest(target: String, body: [String: Any]) async throws -> [String: Any] {
guard let url = URL(string: "https://cognito-idp.us-east-1.amazonaws.com/") else {
throw CognitoError.invalidURL
}

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue(target, forHTTPHeaderField: "X-Amz-Target")
request.addValue("application/x-amz-json-1.1", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONSerialization.data(withJSONObject: body, options: [])

let (data, response) = try await URLSession.shared.data(for: request)

if let dataString = String(data: data, encoding: .utf8) {
print("Response Data as String: \(dataString)") //Incorrect username or password
} else {
print("Unable to convert data to string.")
}

guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
throw CognitoError.requestFailed
}

do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
return json
} else {
throw CognitoError.requestFailed
}
} catch {
throw CognitoError.requestFailed
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... ac-or-hkdf
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Расширение API не позволяет авторизоваться из-за неправильного hmac или hkdf
    Anonymous » » в форуме Python
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Python hmac и C# hmac
    Anonymous » » в форуме C#
    0 Ответы
    29 Просмотры
    Последнее сообщение Anonymous
  • Python hmac и C# hmac
    Anonymous » » в форуме Python
    0 Ответы
    32 Просмотры
    Последнее сообщение Anonymous
  • Ключи HMAC в System.keys Collection и потоковая потока мониторинга ключей HMAC
    Anonymous » » в форуме JAVA
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous
  • Ключи HMAC в System.keys Collection и потоковая потока мониторинга ключей HMAC
    Anonymous » » в форуме JAVA
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»