2011-02-12 5 views
42
내가 전에 앱 구매에 구현 된 적이

에서 앱 구매 영수증에 저장, 그래서 MKStoreKit 래퍼를 사용하고 작업 구현이있다. MKStoreKit은 UserDefaults .plist의 모든 영수증을 BOOL로 유지하므로 해적들이 인앱 구매를 "금이 간"상태로 배포하는 것은 매우 간단합니다. 첫 번째 구매가 이루어지면 번들을 배포하고 .plist를 다시 만들어 IAP 잠금을 해제 할 수 있습니다.응용 프로그램 키 체인

나는 아이폰 OS 키 체인에에서 앱 구매 검증 데이터를 생성하는 MKStoreKit을 확장하고 싶습니다. 사용자에게 비용을 지불하지 못하거나 신뢰할 수 없거나 그 일을하는 것이 전반적으로 좋지 않은 이유가 될 수있는 단점이나 가능한 이유가 있습니까? 나는 불법 복제가 불가피하다는 것을 알고 있으며 유료 사용자를 멀리하고 싶지는 않지만 분명히 UserDefaults .plist는 너무 쉽게 우회 할 수 있다고 생각합니다. 구매가 이루어질 때 내 시나리오에서

는 단순한 문자열은 키 체인에 투입 될 것이다. 그렇게하면 바이너리가 배포되면 unlockable이 이미 활성화되지 않은 것입니다. 물론, 해결 방법을 생각해 낼 수도 있지만, 좀 더 많은 노력이 필요하며 TRUE/FALSE 플래그를 찾아서 항상 올바른 값을 반환하는 방법을 알아야합니다. 난독 화를 통해이를 추적하기가 약간 더 어려워 질 수도 있습니다.

통찰력의 모든 주셔서 감사합니다 내가 의무 피할 불법 복제를 방지 답변을 주셔서 감사합니다, 거래 -에 -이 응답합니다. 나는이 솔루션의 기술적 생존 가능성에 더 관심이 있습니다.

+1

일이 내 이익에 관련이있다. 현재 장치 식별자에 문자열 (소금)을 추가하고 md5를 함께 사용하여 userdefaults에 저장합니다. –

+0

매우 근사합니다. 그렇게하면 iTunes 자격 증명이 없어도 다른 장치에서 인증되지 않습니다. – Justin

+1

기록을 위해 귀하가 개입했는지 여부는 확실하지 않지만 MKStoreKit은 iOS 키 체인에 유효성 검사 데이터를 생성합니다. 사용자 업그레이드하면 새로운 장치로 백업, 장치 ID (또는 무엇이든 동일하게 수행하는 UUID 교체에서 복원 - MatthiasBauch의 접근 방식은 나쁜 생각은 아마 @ 즉, 공식적으로 – SAHM

답변

54

우리는 우리의 우리의 애플 리케이션의 정확히 그렇게 그것은 great.It의 당신이 전체 버전으로 업그레이드 할 수있는 무료 응용 프로그램을 작동하고 우리는 키 체인에 업그레이드 표시를 저장합니다. 업그레이드 표시기는 사용자가 선택한 임의의 문자열이지만 키 체인의 용도로는 암호로 취급됩니다. 즉, kSecValueData의 값은 키 체인에서 암호화됩니다. 이 접근법에 대한 좋은 보너스는 키 체인 항목이 앱과 별도로 저장되기 때문에 사용자가 앱을 삭제했다가 나중에 다시 설치하면 모든 기능이 마술처럼 다시 활성화된다는 것입니다. 그리고 사용자 기본값에 뭔가를 저장하는 것보다 추가 작업이 적어 그만한 가치가 있다고 판단했습니다. upgradeItemData이 전무 인 경우

NSMutableDictionary* query = [NSMutableDictionary dictionary]; 

[query setObject: (id) kSecClassGenericPassword forKey: (id) kSecClass]; 
[query setObject: kYourUpgradeStateKey   forKey: (id) kSecAttrService]; 
[query setObject: (id) kCFBooleanTrue   forKey: (id) kSecReturnData]; 

NSData* upgradeItemData = nil; 
SecItemCopyMatching ((CFDictionaryRef) query, (CFTypeRef*) &upgradeItemData); 
if (!upgradeItemData) 
{ 
    // Disable feature 
} 
else 
{ 
    NSString* s = [[[NSString alloc] 
         initWithData: upgradeItemData 
          encoding: NSUTF8StringEncoding] autorelease]; 

    if ([s isEqualToString: kYourUpgradeStateValue]) 
    { 
     // Enable feature 
    } 
} 

, 다음 키가 존재하지 않습니다

여기
NSMutableDictionary* dict = [NSMutableDictionary dictionary]; 

[dict setObject: (id) kSecClassGenericPassword forKey: (id) kSecClass]; 
[dict setObject: kYourUpgradeStateKey   forKey: (id) kSecAttrService]; 
[dict setObject: kYourUpgradeStateValue   forKey: (id) kSecValueData]; 

SecItemAdd ((CFDictionaryRef) dict, NULL); 

어떻게 그 값을 확인하기 위해 보안 항목을 찾을 수있다 :

여기에 보안 항목을 만드는 방법 그래서 당신은 업그레이드가 존재하지 않는다고 가정 할 수 있습니다. 또는 우리가하는 일은 업그레이드되지 않은 것을 의미합니다.

업데이트 (그것을 지적 주셔서 감사합니다 @Luis)

추가 kSecReturnData는

Code on GitHub (ARC variant)

+0

좋은 답변, 많이 감사합니다 – Justin

+0

좋은 물건. 더 많은 사람들이 앱으로이 작업을 수행해야합니다. 많은 앱이 plist에 물건을 저장합니다. iExplorer와 같은 도구로 쉽게 편집 할 수 있으며 jailbroken 장치가 필요합니다. – Evan

+0

당신은 은'추가해야합니다 [(ID) kCFBooleanTrue forKey : 쿼리의 setObject (ID) kSecReturnData]' 앱 (예 : 네비게이션 응용 프로그램) 백그라운드에서 실행중인 경우 SecItemCopyMatching – Luis