Skip to content

Subclassing APLConfiguration encrypted NSString

Electric Bolt edited this page Jun 21, 2020 · 7 revisions

Documentation

HOME

UPGRADE 1.4.0 to 2.2.0
UPGRADE 2.1.1 to 2.2.0

INTEGRATION

EXAMPLES
    AppfigurateExample
    ActionExample Extension
    WatchExample
    WatchExample Intent Extension

CONFIGURATION
    APLConfiguration subclass
        Custom executable actions
        Supported property types
            BOOL
            NSInteger
            float
            double
            plain NSString
            encrypted NSString
               ENCRYPTED_STRING
               Best practice
               String Encryption util
                  Troubleshooting
        UISlider icon types
        Overrides
    Advanced configuration
        App Startup
        Info.plist
        WCSession
    Additional functions
    Display overridden config

SECURITY
    Export compliance
    Best practice
    App Store compliance

TESTING
    Automation testing

Clone this wiki locally

  Encryption best practice

  Objective-C NSString editable list implementation
  Objective-C ENCRYPTED_STRING macro
  Objective-C ENCRYPTED_STRING_IOS_WATCHOS macro

  Swift String editable list implementation
  Swift ENCRYPTED_STRING function
  Swift ENCRYPTED_STRING_IOS_WATCHOS function

Encryption best practice

Using ENCRYPTED_STRING and ENCRYPTED_STRING_IOS_WATCHOS guarantees that the plain text of the list item values will not be included in the resulting application binary, only the cipher text. The cipher text can only be decrypted by Appfigurate using the correct private key.

You can verify that the plain text is not included in the RELEASE application binary using the macOS strings tool as follows:

Terminal

> cd ~/Library/Developer/Xcode/DerivedData/AppfigurateWorkspace-esajjxyazigjunfteipthjfiobut/Build/Products/Release-iphoneos/AppfigurateExample (iOS).app
> strings AppfigurateExample | grep "https://dev.appfigurate.io/list"     // no results
> strings AppfigurateExample | grep "H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="     // prints H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ==

It is best practice to use ENCRYPTED_STRING and ENCRYPTED_STRING_IOS_WATCHOS to encrypt sensitive information such as server urls (e.g. internal test environments), rather than expose them as plain text.

Objective-C

The default value of an encrypted NSString is nil. You can change the default value of the property by assigning a new plain text value in an overridden reset method.

@property(strong) NSString propertyName;

This page describes encrypted strings. Appfigurate also supports plain textual strings.

Objective-C NSString editable list implementation

ENCRYPTED_STRING_PROPERTY_LIST_EDIT(propertyName, regex, description, restart, ...)

The NSString property can be changed in Appfigurate by allowing the user to select from a predefined list of valid choices. The user can customize the list adding by additional values using a UITextField and a regular expression validating input.

Objective-C example

@interface Configuration : APLConfiguration
@property(nonatomic, strong) NSString url;
@end

@implementation Configuration

ENCRYPTED_STRING_PROPERTY_LIST_EDIT(url, @"https://[\\w\\.-]+\\.appfigurate.io/.*", @"url", NO, @{
    @"Dev": ENCRYPTED_STRING_IOS_WATCHOS(@"https://dev.appfigurate.io/list",@"H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ==",@""JaMa92a122zZs...Mnz23KamnZ0a="), 
    @"Test": ENCRYPTED_STRING_IOS_WATCHOS(@"https://test.appfigurate.io/list",@"PL+UtWB9WHuO7...aX5BdNqEcbmQE=",@"Na1MSadBCaDD...KKANZias199Km=="), 
    @"Prod": ENCRYPTED_STRING_IOS_WATCHOS(@"https://m.appfigurate.io/list",@"IxrJFFUarMg6p...E7OWYOC2uJ1AQ==",@"aZSDIMSaasiaM...8SKS1MMahfpIa=")});
...

Appfigurate UI element example

Objective-C ENCRYPTED_STRING macro

ENCRYPTED_STRING(plaintext, ciphertext)

For an iOS app where the APLConfiguration subclass has one public key use the ENCRYPTED_STRING macro for each list item in the ENCRYPTED_STRING_PROPERTY_LIST_EDIT.

The first parameter of the ENCRYPTED_STRING macro is the plain text, and will be used by DEBUG builds. The second parameter of the ENCRYPTED_STRING macro is the cipher text, and will be used by RELEASE builds. To generate the cipher text, use the macOS AppfigurateSE String Encryption utility or source editor extension for Xcode.

Objective-C example

ENCRYPTED_STRING_PROPERTY_LIST_EDIT(url, @"https://[\\w\\.-]+\\.appfigurate.io/.*", @"url", NO, @{
    @"Dev":ENCRYPTED_STRING(@"https://dev.appfigurate.io/list",@"H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="), 
    @"Test":ENCRYPTED_STRING(@"https://test.appfigurate.io/list",@"PL+UtWB9WHuO7...aX5BdNqEcbmQE="), 
    @"Prod":ENCRYPTED_STRING(@"https://m.appfigurate.io/list",@"IxrJFFUarMg6p...E7OWYOC2uJ1AQ==")});

Objective-C ENCRYPTED_STRING_IOS_WATCHOS macro

ENCRYPTED_STRING_IOS_WATCHOS(plaintext, ciphertextIOS, ciphertextWatchOS)

For an iOS and watchOS app where the APLConfiguration subclass has two public keys, use the ENCRYPTED_STRING_IOS_WATCHOS macro for each list item in the ENCRYPTED_STRING_PROPERTY_LIST_EDIT macro.

The first parameter of the ENCRYPTED_STRING macro is the plain text, and will be used by DEBUG builds. The second and third parameters of the ENCRYPTED_STRING macro are the cipher text for iOS and watchOS apps, and will be used by RELEASE builds. To generate the cipher text, use the macOS AppfigurateSE String Encryption utility or source editor extension for Xcode.

Objective-C example

ENCRYPTED_STRING_PROPERTY_LIST_EDIT(url, @"https://[\\w\\.-]+\\.appfigurate.io/.*", @"url", NO, @{
    @"Dev": ENCRYPTED_STRING_IOS_WATCHOS(@"https://dev.appfigurate.io/list",@"H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ==",@""JaMa92a122zZs...Mnz23KamnZ0a="), 
    @"Test": ENCRYPTED_STRING_IOS_WATCHOS(@"https://test.appfigurate.io/list",@"PL+UtWB9WHuO7...aX5BdNqEcbmQE=",@"Na1MSadBCaDD...KKANZias199Km=="), 
    @"Prod": ENCRYPTED_STRING_IOS_WATCHOS(@"https://m.appfigurate.io/list",@"IxrJFFUarMg6p...E7OWYOC2uJ1AQ==",@"aZSDIMSaasiaM...8SKS1MMahfpIa=")});

Swift

The default value of an encrypted String is nil. You can change the default value of the property by assigning a new plain text value in an overridden reset method.

This page describes encrypted strings. Appfigurate also supports plain textual strings.

Swift String editable list implementation

@EncryptedStringPropertyListEdit(regex, description, encrypted, restart, values)
var propertyName: String

The String property can be changed in Appfigurate by allowing the user to select from a predefined list of valid choices. The user can customize the list adding by additional values using a UITextField and a regular expression validating input. The encrypted parameter of EncryptedStringPropertyListEdit must be the result of calling the ENCRYPTED() function. e.g.

... description: "url", encrypted: ENCRYPTED(), restart: ...

Swift example

    @EncryptedStringPropertyListEdit(regex: #"https://[\w\.-]+\.appfigurate.io/.*"#, description: "url", encrypted: ENCRYPTED(), restart: false, values: [
        "Dev":ENCRYPTED_STRING_IOS_WATCHOS("https://dev.appfigurate.io/list","H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ==","JaMa92a122zZs...Mnz23KamnZ0a="),
        "Test":ENCRYPTED_STRING_IOS_WATCHOS("https://test.appfigurate.io/list","PL+UtWB9WHuO7...aX5BdNqEcbmQE=","Na1MSadBCaDD...KKANZias199Km=="),
        "Prod":ENCRYPTED_STRING_IOS_WATCHOS("https://m.appfigurate.io/list","IxrJFFUarMg6p...E7OWYOC2uJ1AQ==","aZSDIMSaasiaM...8SKS1MMahfpIa=")])
    var url: String
    ...

Appfigurate UI element example

Swift ENCRYPTED_STRING function

func ENCRYPTED_STRING(_ plaintext: String, _ ciphertext: String) -> String

For an iOS app where the APLConfiguration subclass has one public key use the ENCRYPTED_STRING function for each list item in the @EncryptedStringPropertyListEdit.

The first parameter of the ENCRYPTED_STRING function is the plain text, and will be used by DEBUG builds. The second parameter of the ENCRYPTED_STRING macro is the cipher text, and will be used by RELEASE builds. To generate the cipher text, use the macOS AppfigurateSE String Encryption utility or source editor extension for Xcode.

Swift example

    @EncryptedStringPropertyListEdit(regex: #"https://[\w\.-]+\.appfigurate.io/.*"#, description: "url", encrypted: ENCRYPTED(), restart: false, values: [
        "Dev":ENCRYPTED_STRING("https://dev.appfigurate.io/list","H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="),
        "Test":ENCRYPTED_STRING("https://test.appfigurate.io/list","PL+UtWB9WHuO7...aX5BdNqEcbmQE="),
        "Prod":ENCRYPTED_STRING("https://m.appfigurate.io/list","IxrJFFUarMg6p...E7OWYOC2uJ1AQ==")])
    var url: String

Swift ENCRYPTED_STRING_IOS_WATCHOS function

func ENCRYPTED_STRING_IOS_WATCHOS(_ plaintext: String, _ ciphertextIOS: String, _ ciphertextWatchOS: String) -> String

For an iOS and watchOS app where the APLConfiguration subclass has two public keys, use the ENCRYPTED_STRING_IOS_WATCHOS function for each list item in the @EncryptedStringPropertyListEdit.

The first parameter of the ENCRYPTED_STRING function is the plain text, and will be used by DEBUG builds. The second and third parameters of the ENCRYPTED_STRING function are the cipher text for iOS and watchOS apps, and will be used by RELEASE builds. To generate the cipher text, use the macOS AppfigurateSE String Encryption utility or source editor extension for Xcode.

Swift example

@EncryptedStringPropertyListEdit(regex: #"https://[\w\.-]+\.appfigurate.io/.*"#, description: "url", encrypted: ENCRYPTED(), restart: false, values: [
    "Dev":ENCRYPTED_STRING_IOS_WATCHOS("https://dev.appfigurate.io/list","H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ==","JaMa92a122zZs...Mnz23KamnZ0a="),
    "Test":ENCRYPTED_STRING_IOS_WATCHOS("https://test.appfigurate.io/list","PL+UtWB9WHuO7...aX5BdNqEcbmQE=","Na1MSadBCaDD...KKANZias199Km=="),
    "Prod":ENCRYPTED_STRING_IOS_WATCHOS("https://m.appfigurate.io/list","IxrJFFUarMg6p...E7OWYOC2uJ1AQ==","aZSDIMSaasiaM...8SKS1MMahfpIa=")])
var url: String
...

Swift ENCRYPTED function

func ENCRYPTED() -> Bool

Used in conjunction with the @EncryptedStringPropertyListEdit property wrapper. The encrypted parameter of @EncryptedStringPropertyListEdit must be the result of calling the ENCRYPTED() function. e.g.

... description: "url", encrypted: ENCRYPTED(), restart: ...

The function returns true if the calling app has been compiled in RELEASE mode or false if the calling app has been compiled in DEBUG mode.

Warning: This function will behave incorrectly if the apps build settings Swift compiler - Code generation ‣ Optimization Level is set to Optimize for Size (-Osize). The default Swift compiler optimization levels are No Optimization for DEBUG builds and Optimize for Speed -Ospeed for RELEASE builds. If you must use -Osize, then implement your own isEncrypted() style function as follows:

func isEncrypted() {
#if DEBUG
	return false
#else
	return true
#end
}

Then call your own isEncrypted() function instead of the provided ENCRYPTED() function e.g.

... description: "url", encrypted: isEncrypted(), restart: ...