2011-02-12 13 views
42

Nunca he implementado In App Purchase antes, así que utilicé el contenedor MKStoreKit y tengo una implementación en funcionamiento. MKStoreKit mantiene todos los recibos en UserDefaults .plist como BOOL, por lo que es muy simple para los piratas distribuir las compras en la aplicación en un estado "agrietado". Una vez que se realiza la primera compra, el paquete se puede distribuir y .plist se puede volver a crear para permitir que IAP se desbloquee.Almacenar en App Comprar recibos en la aplicación Keychain

Me gustaría extender MKStoreKit para crear los datos de validación en la compra de aplicaciones en el llavero de iOS. ¿Hay alguna desventaja o posible razón para que esto no funcione para los usuarios que pagan, no sea confiable o cualquier otra razón por la que sería una mala idea general hacer esto? Entiendo que la piratería es inevitable, y definitivamente no quiero alienar a los usuarios que pagan, pero creo que la lista de UserDefaults es demasiado fácil de eludir.

En mi caso, una cadena simple se pondría en el llavero cuando se realiza la compra. De esta forma, si el binario se distribuye, los desbloqueables no están habilitados. Claro, sería posible encontrar una solución, pero tomaría un poco más de esfuerzo y sabría cómo encontrar la bandera VERDADERO/FALSO y hacer que siempre devuelva el valor correcto. A través de la ofuscación podría incluso hacer que sea un poco más difícil rastrear eso.

Gracias por todos sus comentarios y agradezco las respuestas que evitan las respuestas obligatorias inevitables de piratería y trato oportuno. Estoy más interesado en las viabilidades técnicas de esta solución.

+1

+1 Esto es relevante para mis intereses. Actualmente agrego algo de cadena (como sal) al identificador del dispositivo y md5 todo eso junto y lo almacena en los valores predeterminados del usuario. –

+0

Muy bueno. De esta forma, no se autenticará en otro dispositivo sin tener credenciales de iTunes. – Justin

+1

Para el registro, no estoy seguro si estuvo involucrado o no, pero MKStoreKit ahora crea datos de validación en el llavero de iOS. – SAHM

Respuesta

54

Hacemos exactamente eso en nuestras aplicaciones y funciona muy bien. Es una aplicación gratuita que puede actualizar a una versión completa y almacenamos el indicador de actualización en el llavero. El indicador de actualización es una cadena arbitraria que usted elige, pero a los efectos del llavero se trata como una contraseña, es decir, el valor de kSecValueData está encriptado en el llavero. Una buena ventaja de este enfoque es que si el usuario elimina la aplicación y luego la vuelve a instalar, todo se vuelve a habilitar como magia porque los elementos del llavero se almacenan por separado de la aplicación. Y es tan poco el trabajo adicional sobre el almacenamiento de algo en los valores predeterminados del usuario que decidimos que valió la pena.

Aquí es cómo crear el elemento de seguridad:

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); 

Aquí es cómo encontrar el elemento de seguridad para comprobar su valor:

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 
    } 
} 

Si upgradeItemData es nula, entonces no existe la clave entonces puede suponer que la actualización no está allí o, lo que hacemos, tiene un valor que significa que no se actualizó.

actualización

Agregado kSecReturnData (Gracias @Luis por señalarlo)

Code on GitHub (ARC variant)

+0

Gran respuesta, muy apreciada – Justin

+0

Cosas buenas. Más personas necesitan hacer esto con sus aplicaciones. Tantas aplicaciones simplemente almacenan cosas en el plist. Es fácilmente editable con una herramienta como iExplorer y requiere un dispositivo con jailbreak. – Evan

+0

Es posible que tenga que añadir '[consulta setObject: (id) kCFBooleanTrue forKey: (id) kSecReturnData];' antes de llamar SecItemCopyMatching – Luis

Cuestiones relacionadas