AWS Cognito用户身份validation缺少必需参数SRP_A

我正在尝试使用AWS Cognito服务通过ruby SDK进行用户身份validation。

我能够签名,使用这些方法确认sign_up进程

resp = client.sign_up({ client_id: "ClientIdType", secret_hash: "SecretHashType", username: "UsernameType", password: "PasswordType", user_attributes: [{ name:"AttributeNameType", value: "AttributeValueType", }], validation_data: [{ name: "AttributeNameType", value: "AttributeValueType", }] }) 

和confirm_sign_up使用

  resp = client.confirm_sign_up({client_id: "ClientIdType", secret_hash: "SecretHashType", username: "UsernameType", confirmation_code: "ConfirmationCodeType" }) 

但是在尝试通过initiate_auth登录用户时,我收到一个错误, 缺少必需的参数SRP_A

 cog_provider.initiate_auth({client_id: "xxxxxxxxx", auth_parameters: { username: "xxx", password: "xxx"}, auth_flow: "USER_SRP_AUTH"}) 

SRP_A指示在哪里找到它。

我已经搜索过这个问题,建议使用admin_initiate_auth方法登录我认为不是最佳做法的用户。

是的,SRP_A是安全远程密码协议定义的大整数。 您是尝试执行SRP还是仅使用用户名和密码进行身份validation。 对于用户名/密码身份validation,您应该使用AdminInitiateAuth操作。

在我们的SDK中,您可以看到需要计算和传递的参数。 以Javascript SDK为例:

https://github.com/aws/amazon-cognito-identity-js/blob/master/src/CognitoUser.js#L152

或者在Android SDK中:

https://github.com/aws/aws-sdk-android/blob/master/aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/mobileconnectors/cognitoidentityprovider/CognitoUser.java#L2123

对于AWS Java SDK:

这是管理这个的类:

 /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.math.pro.ak.util.cognito; import com.amazonaws.AmazonClientException; import com.amazonaws.util.StringUtils; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; /** * * @author marcus */ public class AuthenticationHelper { private BigInteger a; private BigInteger A; private String poolName; public AuthenticationHelper(String userPoolName) { do { a = new BigInteger(EPHEMERAL_KEY_LENGTH, SECURE_RANDOM).mod(N); A = GG.modPow(a, N); } while (A.mod(N).equals(BigInteger.ZERO)); if (userPoolName.contains("_")) { poolName = userPoolName.split("_", 2)[1]; } else { poolName = userPoolName; } } public BigInteger geta() { return a; } public BigInteger getA() { return A; } private static final String HEX_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; private static final BigInteger N = new BigInteger(HEX_N, 16); private static final BigInteger GG = BigInteger.valueOf(2); private static final BigInteger KK; private static final int EPHEMERAL_KEY_LENGTH = 1024; private static final int DERIVED_KEY_SIZE = 16; private static final String DERIVED_KEY_INFO = "Caldera Derived Key"; private static final ThreadLocal THREAD_MESSAGE_DIGEST = new ThreadLocal() { @Override protected MessageDigest initialValue() { try { return MessageDigest.getInstance("SHA-256"); } catch (final NoSuchAlgorithmException e) { throw new AmazonClientException("Exception in authentication", e); } } }; private static final SecureRandom SECURE_RANDOM; static { try { SECURE_RANDOM = SecureRandom.getInstance("SHA1PRNG"); final MessageDigest messageDigest = THREAD_MESSAGE_DIGEST.get(); messageDigest.reset(); messageDigest.update(N.toByteArray()); final byte[] digest = messageDigest.digest(GG.toByteArray()); KK = new BigInteger(1, digest); } catch (final NoSuchAlgorithmException e) { throw new AmazonClientException(e.getMessage(), e); } } public byte[] getPasswordAuthenticationKey(String userId, String userPassword, BigInteger B, BigInteger salt) { // Authenticate the password // u = H(A, B) final MessageDigest messageDigest = THREAD_MESSAGE_DIGEST.get(); messageDigest.reset(); messageDigest.update(A.toByteArray()); final BigInteger u = new BigInteger(1, messageDigest.digest(B.toByteArray())); if (u.equals(BigInteger.ZERO)) { throw new AmazonClientException("Hash of A and B cannot be zero"); } // x = H(salt | H(poolName | userId | ":" | password)) messageDigest.reset(); messageDigest.update(poolName.getBytes(StringUtils.UTF8)); messageDigest.update(userId.getBytes(StringUtils.UTF8)); messageDigest.update(":".getBytes(StringUtils.UTF8)); final byte[] userIdHash = messageDigest.digest(userPassword.getBytes(StringUtils.UTF8)); messageDigest.reset(); messageDigest.update(salt.toByteArray()); final BigInteger x = new BigInteger(1, messageDigest.digest(userIdHash)); final BigInteger s = (B.subtract(KK.multiply(GG.modPow(x, N))) .modPow(a.add(u.multiply(x)), N)).mod(N); Hkdf hkdf = null; try { hkdf = Hkdf.getInstance("HmacSHA256"); } catch (final NoSuchAlgorithmException e) { throw new AmazonClientException(e.getMessage(), e); } hkdf.init(s.toByteArray(), u.toByteArray()); final byte[] key = hkdf.deriveKey(DERIVED_KEY_INFO, DERIVED_KEY_SIZE); return key; } } 

并调用此方法: userAuth.put("SRP_A", new AuthenticationHelper(request.getUsername()).getA().toString(16));

Interesting Posts