Unity3D/Tips

[펌] UDID, UUID, 유니크 한 고정 값 완결

blueasa 2017. 1. 4. 17:50

UDID, UUID, 유니크 한 고정 값 완결



먼저 각 명칭에 대해 알아보도록 한다.



UUID - Universally Unique Identifire ( 시간, 공간을 이용하여 뽑아낸 128bit (중복되지 않는) 값 )

GUID - Globaly Unique Identifire ( UUID 와 같은 MS 에서 사용하는 값 )

UDID - Unique Device Identifire ( 기기 별 고유 식별 값 )


Vendor Identifier - 공급 업체 식별자

Advertising Identifier - 광고 식별자





기기별 고유값을 얻어오기 위해 이전 ( IOS 4 이하 ) 에서는 UDID 값을 가져와 사용 할 수 있었다.

그러나 이후 해킹 등에 취약하다는 이유로 사용 금지 시키고 IOS 5 부터는 UUID 를 사용하라고 권고하였다.


CFUUIDRef udid = CFUUIDCreate(NULL);
NSString *udidString = (NSString *) CFUUIDCreateString(NULL, udid);

위는 UUID 얻는 방법이다.  ( IOS 5 에서 )

IOS 6 에서는 아래와 같이 간편하게 얻을 수 있다.


NSString *uuid = [[NSUUID UUID] UUIDString];

이는 시간, 공간 값을 이용하여 128bit 를 이용해 얻어내여 중복 가능성이 없다고 한다.


얻어진 결과의 예제는 는 다음과 같다.

BE5BA3D0-971C-4418-9ECF-E2D1ABCB66BE


이를 사용하여, 유니크한 값으로 사용할 수는 있다.

다만 호출시마다 유니크한 값을 준다.


따라서 이 값으로 기기를 식별하거나 할 수 없다.


이를 사용하기 위해 키체인을 사용하여 저장하는 방법도 있다.

해당 방법은 아래와 같다.


접기

[UUID 키체인 저장 방법]

KeyChain API들은 Security.framework에 정의 되어 있는데 C함수로 되어 있고 API를 쓰는 것이 쉽지 않아 애플에서 쉽게 사용할 수 있게 KeychainItemWrapper 예제 클래스를 제공하고 있다.

일단 KeychainItemWrapper를 다운 받고 프로젝트에 추가해야 한다. (download)


    KeychainItemWrapper.h

    KeychainItemWrapper.m


아래는 UUID를 생성해서 KeyChain에 저장하는 함수 이다.

//처음에 UUID KeyChain에서 불러오는데 nil이라면 UUID 생성해서 KeyChain 저장한다.

//저장 후에 다시 함수를 호출 하면 저장된 값을 리턴한다.

- (NSString*) getUUID

{

    // initialize keychaing item for saving UUID.

    KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"UUID" accessGroup:nil];

   

    NSString *uuid = [wrapper objectForKey:(__bridge id)(kSecAttrAccount)];


    if( uuid == nil || uuid.length == 0)

    {

        // if there is not UUID in keychain, make UUID and save it.

        CFUUIDRef uuidRef = CFUUIDCreate(NULL);

        CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);

        CFRelease(uuidRef);

        uuid = [NSString stringWithString:(__bridge NSString *) uuidStringRef];

        CFRelease(uuidStringRef);

        

        // save UUID in keychain

        [wrapper setObject:uuid forKey:(__bridge id)(kSecAttrAccount)];

    }

    

    return uuid;

}


KeyChin에 대하여 설명을 하면..

KeychainItemWrapper를 사용하여 키체인에 값을 등록하게 되는데..

- (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup


//내부 앱에서만 사용할 경우 

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"UUID" accessGroup:nil];


//Keychain Group끼리 공유할 경우

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"UUID" accessGroup:@"???????.com.yourcompany.GenericKeychainSuite"];


KeychainItemWrapper 인스턴스를 생성할 때 저장할 값을 구별할 이름(initWithIdentifier)과 accessGroup을 지정해야 한다.


- accessGroup은 KeyChain Group을 지정하는 것인데 nil이면 내부 앱에서만 사용하는 것이고 nil이 아닌 값을 사용하면 같은 Keychain Group을 사용하는 앱에서 공유가 가능하다.


- Keychain Group을 확인하는 방법은 xcode6에서는 프로젝트 > TARGETS 프로젝트 > capabilities > Keychain Sharing 에서 확인하면 된다. (xcode5, 6)


- (id)objectForKey:(id)key


//키체인에 저장된 값을 가져온다.

NSString *uuid = [wrapper objectForKey:(__bridge id)(kSecAttrAccount)];


- (void)setObject:(id)inObject forKey:(id)key


// 키체인에 저장한다.

[wrapper setObject:uuid forKey:(__bridge id)(kSecAttrAccount)]; 


- KeychainItemWrapper를 사용하여 데이터를 저장할 때 사용할 수 있는 상수는 아래와 같다.

  (https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/index.html)

   1) kSecAttrAccount : Account 정보

   2) kSecAttrLabel : 라벨 정보

   3) kSecAttrDescription : 설명

   4) kSecValueData : Data


- 예를들어 암호화된 비밀번호를 저장하기 위해서 kSecValueData를 Key로 하고 암호화된 비밀번호를 InObject로 하면 된다. 로그인 이름을 저장한다면 kSecAttrAccount를 Key로 하고 저장하면 된다.


[참고]

http://10apps.tistory.com/archive/20130403

http://dev-metal.blogspot.kr/2010/08/howto-use-keychain-in-iphone-sdk-to.html



다음으로 

identifireForVender 의 설명이다.


1. 설치된 앱에서 호출 시 매번 같은 값을 리턴한다.

2. 다만 앱 재 설치 시 값이 바뀐다.

3. 같은 벤더를 사용하는 경우 값이 유지 된다,

    다만같은 벤더를 사용하는 앱을 모두 지울 경우 마찬가지로 값이 바뀐다.


따라서 identifireForVender 값도 영원한 기기 식별자로 사용 할 수 없다.






유니티의 SystemInfo.deviceUniqueIdentifier



Android 


 - readPhoneState 퍼미션이 설정되어있을 경우

   IMEI 값 리턴

   ex) 51F30A87-BBFA-128F-E915-C92391D2F164


 - readPhoneState 퍼미션이 설정되어있지 않을 경우

   AndroidID 값 리턴

   ex) 8127362567812635



IOS


 - IOS6 버젼 이전

   MAC_ADRESS 값을 해싱 하여 리턴


 - IOS7 버젼 이후

   ASIdentifierManager advertisingIdentifier 값을 리턴

   어떤 이유에서 이 값을 리턴 할 수 없는 경우 

   UIDevice identifierForVendor 를 리턴


[출처] http://flystone.tistory.com/149

반응형