2

루비 SDK를 통해 사용자 인증에 AWS Cognito 서비스를 사용하려고합니다.AWS Cognito 사용자 인증 SRP_A가 누락되었습니다.

나는

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

를 사용하는 방법
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

를 사용하여 sign_up 과정을 확인 할 수 sign_up 할 수 있습니다하지만 오류를 얻고있다 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 방법을 사용하는 것이 좋습니다.

답변

3

예, SRP_A는 보안 원격 암호 프로토콜에서 정의한 큰 정수입니다. SRP를하거나 단지 사용자 이름과 비밀번호로 인증하려고하십니까? 사용자 이름/비밀번호 인증을 위해서는 AdminInitiateAuth 조작을 사용해야합니다.

Google SDK에서는 계산하고 전달해야하는 매개 변수를 볼 수 있습니다. 예를 들어, 자바 스크립트 SDK를 타고 : https://github.com/aws/amazon-cognito-identity-js/blob/master/src/CognitoUser.js#L152

또는 안드로이드 SDK에서

가 :

AWS 자바 SDK를 들어 https://github.com/aws/aws-sdk-android/blob/master/aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/mobileconnectors/cognitoidentityprovider/CognitoUser.java#L2123

+0

AdminInitiateAuth를 사용하는 것이 가장 좋은 방법입니까? SRP_A 값을 얻을 수있는 방법이 있습니까? –

+0

AdminInitiateAuth는 보안 서버 환경에서만 사용하기위한 것입니다. SRP_A는 기본적으로 클라이언트 측에서 생성 된 큰 정수입니다. 예를 들어 자바에서는 다음을 할 수 있습니다 : a = new BigInteger (EPHEMERAL_KEY_LENGTH, SECURE_RANDOM) .mod (N); A = g.modPow (a, N); https://github.com/aws/aws-sdk-android/blob/master/aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/mobileconnectors/cognitoidentityprovider/CognitoUser.java#L2440 여기서 N은입니다. 큰 총리 –

0

: 여기

이를 관리 할 수있는 클래스입니다 :

/* 
* 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<MessageDigest> THREAD_MESSAGE_DIGEST = new ThreadLocal<MessageDigest>() { 
     @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));