MADP에서는 공개키 고정방식을 위한 방식을 제시하며 각 OS별로 하단의 상세 내용을 참고바랍니다.
( 재품 사용 시 Android 9 이상에서는 적용되지 않을 가능성이 있어 권장하지 않습니다. )
<manifest>
<application
android:name=".implementation.ExtendApplication"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:networkSecurityConfig="@xml/network_security_config"/>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">yourdomain.com</domain>
<pin-set expiration="2026-01-01">
<pin digest="SHA-256">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</pin>
</pin-set>
<!--선택-->
<trust-anchors>
<certificates src="system" /> <!-- 사용자 CA 차단 -->
</trust-anchors>
<!--////////-->
</domain-config>
</network-security-config>
약속된 규격으로 Storage에 인증서의 Pin SHA256키를 등록하면 라이브러리 내에서 처리되는 방식
( MCore 라이브러리 2.1.8.60 이상 지원 )
key | type | Description |
---|---|---|
PINNED_PUBKEY_SHA256 | String | Storage 등록 키 |
도메인("uracle.co.kr") | Dictionary | 공캐키 고정할 도메인 |
pin_end_date | YYYYMMDD | 등록된 Pin SHA256의 유효기간 |
pin_key | String | 서버 인증서의 Pin SHA256 값 |
등록된 key 배열은 OR 연산으로 처리되어 리스트중 하나만 맞으면 PASS 처리된다.
pin_end_date가 지나면 해당 도메인은 Pinning 체크를 하지 않는다.
종단인증서와 중개인증서를 구별하지 않고 처리
통신에 사용되는 도메인(서버)가 여러개인 경우 해당 서버인증서의 key를 모두 등록
예시 1) 스크립트에서 설정
const pinData =
{
"uracle.co.kr": {
"pin_end_date": "20250704",
"pin_key": [
"Bz6dgG7dpIDG6TU5xE3a9M6BkuBFfe71mP4VcGzzg2k=",
"x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4="
]
},
"dev.uracle.co.kr": {
"pin_end_date": "20250101",
"pin_key": [
"i9HaIScvf6T/skE3/A7QOq5n5cTYs8UHNOEFCnkguSI=\""
]
}
}
M.data.storage("PINNED_PUBKEY_SHA256", JSON.stringify(pinData));
예시 2) 네이티브에서 설정
//아래와 같은 형식으로 jsonString 생성
String public_key = "{"
+ "\"uracle.co.kr\": {"
+ "\"pin_end_date\": \"20250704\","
+ "\"pin_key\": ["
+ "\"Bz6dgG7dpIDG6TU5xE3a9M6BkuBFfe71mP4VcGzzg2k=\""
+ ", \"x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=\""
+ "]"
+ "},"
+ "\"dev.uracle.co.kr\": {"
+ "\"pin_end_date\": \"20250521\","
+ "\"pin_key\": ["
+ "\"LuK3yRrm/J4cSJ4DpeqS6bQb8LwKmtcc1mRTUvUj0HE=\""
+ ", \"i9HaIScvf6T/skE3/A7QOq5n5cTYs8UHNOEFCnkguSI=\""
+ "]"
+ "}"
+ "}";
CommonLibUtil.setVariableToStorage(LibDefinitions.str_certificatioin.PINNED_PUBKEY_SHA256, public_key, commHandle.getApplicationContext());
인증서 고정방식, 별도의 처리를 위한 적용 방법
( MCore 라이브러리 2.1.8.60 이상 지원 )
public HttpDefaultNetworkManager() {
super();
//param : SSLSocketFactory 상속받아 작성된 클래스
CommonLibUtil.setSocketFactory(CustomSSLPinningHttpClient.class);
}
key | type | Description |
---|---|---|
NSPinnedDomains | Dictionary | 공개키 고정할 도메인들의 모음 |
도메인("uracle.co.kr") | Dictionary | 공캐키 고정할 도메인 |
NSIncludesSubdomains | Boolean | 서브 도메인을 포함할지에 대한 Boolean값 |
NSPinnedLeafIdentities | Array | 종단인증서의 Pin SHA256 키의 모음 |
NSPinnedCAIdentities | Array | 중개인증서의 Pin SHA256 키의 모음 |
SPKI-SHA256-BASE64 | String | 인증서의 Pin SHA256 키 |
등록된 key 배열은 OR 연산으로 처리되어 리스트중 하나만 맞으면 PASS 처리된다.
종단인증서와 중개인증서는 AND 연산으로 처리되어 각각 등록시 둘다 조건을 충족하여야 PASS 처리된다.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSPinnedDomains</key>
<dict>
<key>uracle.co.kr</key>
<dict>
<key>NSPinnedLeafIdentities</key>
<array>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>LuK3yRrm/J4cSJ4DpeqS6bQb8LwKmtcc1mRTUvUj0HE=</string>
</dict>
</array>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSPinnedCAIdentities</key>
<array>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=</string>
</dict>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=</string>
</dict>
</array>
</dict>
</dict>
</dict>
약속된 규격으로 Storage에 인증서의 Pin SHA256키를 등록하면 라이브러리 내에서 처리되는 방식
( MCore 라이브러리 2.1.8.59 이상 지원 )
key | type | Description |
---|---|---|
PINNED_PUBKEY_SHA256 | String | Storage 등록 키 |
도메인("uracle.co.kr") | Dictionary | 공캐키 고정할 도메인 |
pin_key | Array | 서버 인증서의 Pin SHA256 값 |
pin_end_date | String | SSL Pinning 체크 유효 기간 (YYYYMMDD) |
등록된 key 배열은 OR 연산으로 처리되어 리스트중 하나만 맞으면 PASS 처리된다.
pin_end_date가 지나면 해당 도메인은 Pinning 체크를 하지 않는다.
종단인증서와 중개인증서를 구별하지 않고 처리
(* 루트 인증서는 사용할수 없음 )
예시 1) 스크립트에서 설정
const pinData =
{
"uracle.co.kr":
{
"pin_end_date": "20250704",
"pin_key": ["LuK3yRrm/J4cSJ4DpeqS6bQb8LwKmtcc1mRTUvUj0HE=","x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4="]
},
"dev.uracle.co.kr":
{
"pin_end_date": "20250101",
"pin_key": ["i9HaIScvf6T/skE3/A7QOq5n5cTYs8UHNOEFCnkguSI="]
}
}
M.data.storage("PINNED_PUBKEY_SHA256", JSON.stringify(pinData));
예시 2) 네이티브에서 설정
NSDictionary *uracle_co_kr =
@{
@"pin_end_date": @"20250704",
@"pin_key": @[
@"LuK3yRrm/J4cSJ4DpeqS6bQb8LwKmtcc1mRTUvUj0HE=",
@"x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4="
]
};
NSDictionary *dev_uracle_co_kr =
@{
@"pin_end_date": @"20250101",
@"pin_key": @[
@"i9HaIScvf6T/skE3/A7QOq5n5cTYs8UHNOEFCnkguSI="
]
};
NSDictionary *pinningData = @{
@"uracle.co.kr": uracle_co_kr,
@"dev.uracle.co.kr": dev_uracle_co_kr
};
_setStorageValue(@"PINNED_PUBKEY_SHA256", [pinningData jsonString]);
인증서 고정방식, 별도의 처리를 위한 적용 방법
( MCore 라이브러리 2.1.8.34 이상 지원 )
//HttpDefaultNetworkManager.m
- (void)processWithViewCtrl:(UIViewController *)viewController trcode:(NSString *)path data:(NSString *)data networkoption:(PPNetworkOption *)networkOption delegate:(id<PPNetworkManagerDelegate>)delegate userinfo:(NSArray *)userInfo {
......
......
// Provider 시작
[provider startAsynchronousWithURLSession];
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
// SSL Pinning 관련 커스텀 로직 처리
......
......
if(로직에 따른 조건식)
{
// 인증서를 신뢰
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
else
{
// request를 취소
completionHandler(.cancelAuthenticationChallenge, nil)
}
}