Notice
Recent Posts
Recent Comments
Link
투케이2K
1033. (Android/Java) AWS WebRTC HTTPS 엔드포인트 사용해 ICE 서버 리스트 목록 조회 API AWS4Signer 헤더 생성 방법 본문
Android
1033. (Android/Java) AWS WebRTC HTTPS 엔드포인트 사용해 ICE 서버 리스트 목록 조회 API AWS4Signer 헤더 생성 방법
투케이2K 2025. 10. 10. 20:08728x90
[개발 환경 설정]
개발 툴 : AndroidStudio
개발 언어 : Java / Kotlin

[소스 코드]
// --------------------------------------------------------------------------------------
[개발 및 테스트 환경]
// --------------------------------------------------------------------------------------
- 언어 : Java / Kotlin
- 개발 툴 : AndroidStudio
- 기술 구분 : AWS / AWS4Signer / WebRTC
- 사전) AWS 의존성 부여 설정
// --------------------------------------------
// [Aws build.gradle 라이브러리 정의] : targetSdk 33 ~ 34
// --------------------------------------------
/**
* implementation 'com.amazonaws:aws-android-sdk-kms:2.57.0'
* implementation 'com.amazonaws:aws-android-sdk-s3:2.57.0'
* implementation 'com.amazonaws:aws-android-sdk-iot:2.57.0'
* implementation 'com.amazonaws:aws-android-sdk-mobile-client:2.57.0'
* implementation 'com.amazonaws:aws-android-sdk-kinesisvideo:2.57.0'
* */
- 사전) AWS4Signer 설명 :
>> AWS SigV4 는 AWS API 요청에 인증 정보를 추가하기 위한 AWS 서명 프로토콜입니다
>> AWS SigV4 는 HTTP Authorization 헤더에서 또는 URL의 쿼리 문자열로 표현될 수 있습니다
>> AWS SigV4 요청에 서명하는 이유 :
- 요청자의 ID 확인 : 인증된 요청에는 액세스 키(액세스 키 ID, 비밀 액세스 키)를 사용하여 만든 서명이 필요합니다
- 전송 중인 데이터 보호 : 요청이 전송되는 동안 훼손되는 것을 방지하기 위해 일부 요청 요소를 사용하여 요청의 해시(다이제스트)를 계산하고 결과 해시 값을 요청의 일부로 포함합니다
- 잠재적 재생 공격으로부터 보호 : 대부분의 경우 요청서의 타임스탬프 시간으로부터 5분 이내에 AWS에 요청이 도착해야 합니다 (그렇지 않으면 AWS가 요청을 거부합니다)
>> AWS SigV4 서명 요청 프로세스 :
- 요청 세부 정보를 기반으로 표준 요청 생성
- AWS 자격 증명을 사용하여 서명 계산
- 이 서명을 요청에 Authorization 헤더로 추가
- 사전) GetIceServerConfig 설명 :
>> GetIceServerConfig 는 WebRTC 연결을 구성하는 데 사용할 수 있는 URI, 사용자 이름, 비밀번호를 포함한 ICEInteractive Connectivity Establishment) 서버 구성 정보를 가져옵니다
>> GetIceServerConfig API 를 사용하기 전에 GetSignalingChannelEndpoint API 를 호출하여 HTTPS 엔드포인트를 얻어 온 후 해당 HTTPS 정보를 사용해 를 GetIceServerConfig API 를 요청해야 합니다
>> GetIceServerConfig 를 사용해 얻어온 ICE 구성 요소 정보를 사용하여 TURN (Traversal Using Relays around NAT) 릴레이 서버 인증을 포함하여 WebRTC 연결을 설정합니다
- TURN은 P2P(피어 투 피어) 애플리케이션의 연결성을 개선하는 데 사용되는 프로토콜입니다.
- 클라우드 기반 릴레이 서비스를 제공함으로써 TURN은 하나 이상의 피어가 직접 P2P 연결을 할 수 없는 경우에도 연결이 설정될 수 있도록 보장합니다.
// --------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------
[소스 코드]
// --------------------------------------------------------------------------------------
// --------------------------------------------
// [필요 변수 선언]
// --------------------------------------------
String ACCESS_KEY = "AK...LM"; // IAM 계정 AccessKey
String SECRET_KEY = "mn...si"; // IAM 계정 SecretKey
String REGION = "ap-northeast-1"; // AWS 리전 정보
String HTTPS_ENDPOINT = "https:// ...."; // HTTPS 엔드포인트
String CHANNEL_NAME = "DEVICE_1"; // 신호채널 명칭
String CLIENT_ID = "TEST_CLIENT"; // 접속 시도 클라이언트 고유 아이디 값
// --------------------------------------------
// [AWSCredentials 자격 증명 수행]
// --------------------------------------------
AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY); // TODO [IAM 계정 Key 초기화]
//BasicSessionCredentials credentials = new BasicSessionCredentials(ACCESS_KEY, SECRET_KEY, SESSION_TOKEN); // TODO [STS 임시 정보 초기화]
// --------------------------------------------
// [AWSKinesisVideoClient 생성]
// --------------------------------------------
AWSKinesisVideo awsKinesisVideoClient = new AWSKinesisVideoClient(credentials);
awsKinesisVideoClient.setRegion(Region.getRegion(REGION));
// --------------------------------------------
// [신호 채널 ARN 정보 조회 수행]
// --------------------------------------------
DescribeSignalingChannelRequest arn_request = new DescribeSignalingChannelRequest()
.withChannelName(CHANNEL_NAME);
DescribeSignalingChannelResult arn_result = awsKinesisVideoClient.describeSignalingChannel(arn_request);
ChannelInfo channelInfo = arn_result.getChannelInfo(); // TODO Get ChannelInfo
String CHANNEL_ARN = channelInfo.getChannelARN();
// --------------------------------------------
// [API 요청 서비스 명칭 선언]
// --------------------------------------------
String SERVICE_NAME = "kinesisvideo";
// --------------------------------------------
// [API 요청 endPoint, path, body 정의]
// --------------------------------------------
/*
POST /v1/get-ice-server-config HTTP/1.1
Content-type: application/json
{
"ChannelARN": "string", // (필수 : O) 구성된 피어 간 피어투피어 연결에 사용될 신호 채널의 ARN입니다
"ClientId": "string", // (필수 : X) 시청자의 고유 식별자입니다. 신호 채널 내에서 고유해야 합니다.
"Service": "string", // (필수 : X) 원하는 서비스를 지정합니다. 현재 TURN유효한 값은 뿐입니다.
"Username": "string" // (필수 : X) 자격 증명과 연결할 선택적 사용자 ID입니다.
}
*/
// --------------------------------------------
String iceUrl = HTTPS_ENDPOINT;
String icePath = "/v1/get-ice-server-config";
iceUrl += icePath;
String iceBody = "{\n" +
" \"ChannelARN\": \""+CHANNEL_ARN+"\",\n" +
" \"ClientId\": \""+CLIENT_ID+"\",\n" +
" \"Service\": \"TURN\"\n" +
"}";
// ---------------------------------------------
// [AWS Signature V4 서명 적용]
// ---------------------------------------------
// import com.amazonaws.DefaultRequest;
// import com.amazonaws.Request;
// ---------------------------------------------
// import okhttp3.Request;
// import okhttp3.RequestBody;
// import okhttp3.Response;
// import okio.BufferedSink;
// ---------------------------------------------
com.amazonaws.Request<?> aws_ice_sign_request = new DefaultRequest<Void>(SERVICE_NAME); // TODO Set ServiceName
aws_ice_sign_request.setHttpMethod(HttpMethodName.POST);
aws_ice_sign_request.setEndpoint(URI.create(HTTPS_ENDPOINT)); // TODO Set Https Endpoint
aws_ice_sign_request.setEncodedResourcePath(icePath);
aws_ice_sign_request.addHeader("Content-Type", "application/json");
aws_ice_sign_request.setContent(new ByteArrayInputStream(iceBody.getBytes(StandardCharsets.UTF_8))); // TODO Set Https Request Body
// ---------------------------------------------
// [AWS 서명자 설정]
// ---------------------------------------------
AWS4Signer aws_ice_signer = new AWS4Signer();
aws_ice_signer.setServiceName(SERVICE_NAME); // TODO Set ServiceName
aws_ice_signer.setRegionName(REGION);
aws_ice_signer.sign(aws_ice_sign_request, credentials);
// ---------------------------------------------
// [OKHttp Request.Builder 생성]
// ---------------------------------------------
okhttp3.Request.Builder okIceReqBuilder = new okhttp3.Request.Builder()
.url(iceUrl)
.post(okhttp3.RequestBody.create(iceBody, okhttp3.MediaType.parse("application/json")));
// ---------------------------------------------
// [서명 헤더 추가]
// ---------------------------------------------
for (String key : aws_ice_sign_request.getHeaders().keySet()) {
okIceReqBuilder.header(key, aws_ice_sign_request.getHeaders().get(key));
S_Log.w("KWON_TWOK", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [Header Insert] :: " + String.valueOf(key) + " :: " + String.valueOf(aws_ice_sign_request.getHeaders().get(key)) + " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
/**
* --------------------------------------------------
* TODO 추가 되는 헤더 정보 예시
* --------------------------------------------------
* [Header Insert] :: Authorization :: Authorization :: AWS4-HMAC-SHA256 Credential=AK..7Q/20251009/ap-northeast-1/kinesisvideo/aws4_request, SignedHeaders=host;x-amz-date, Signature=48..fd
* [Header Insert] :: X-Amz-Date :: 20250722T101748Z
* [Header Insert] :: Host :: s-9..e9.kinesisvideo.ap-northeast-1.amazonaws.com
* [Header Insert] :: Content-Type :: application/json
* --------------------------------------------------
* */
}
// ---------------------------------------------
// [리턴 반환 데이터 생성]
// ---------------------------------------------
S_Log._W_(ACTIVITY_NAME + " :: getIceServerList :: AWS WebRTC HTTPS 엔드포인트 사용해 ICE 서버 리스트 목록 조회 API 헤더 생성 요청 성공", new String[]{
"url :: " + String.valueOf(iceUrl),
"headers :: " + String.valueOf(okIceReqBuilder.build().headers().toString())
});
// --------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------
[참고 사이트]
// --------------------------------------------------------------------------------------
[Aws SigV4 인증 및 서명 프로토콜 설명]
https://blog.naver.com/kkh0977/223874467995?trackingCode=blog_bloghome_searchlist
[WebRTC GetIceServerConfig TURN 릴레이 서버 IceServerList 설명]
https://blog.naver.com/kkh0977/224035896944
[WebRTC getSignalingChannelEndpoint HTTPS, WSS 사용 범위 정리]
https://blog.naver.com/kkh0977/224035890592
[WebRTC GetSignalingChannelEndpoint 신호 채널 엔드포인트 설명]
https://blog.naver.com/kkh0977/224035894347
// --------------------------------------------------------------------------------------
728x90
반응형
'Android' 카테고리의 다른 글
Comments
