[{"data":1,"prerenderedAt":2323},["ShallowReactive",2],{"article_list_nharrison_":3},[4],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"publishDate":11,"tags":12,"image":18,"excerpt":10,"body":19,"_type":2314,"_id":2315,"_source":2316,"_file":2317,"_stem":2318,"_extension":2319,"author":2320},"/nharrison/2012-07/core-data","2012-07",false,"","Securing Your Core Data with Transformable Attributes","In order to store private data in an iOS Core Data database, there are several methods available for encryption, including:","2012-07-30",[13,14,15,16,17],"core-data","encryption","ios","security","objective-c","/nharrison/2012-07/img/superman.jpg",{"type":20,"children":21,"toc":2302},"root",[22,29,62,67,74,97,115,135,142,280,286,1026,1037,1042,1047,1082,1088,1541,1575,1586,1599,1604,1610,1642,1680,1706,1737,1742,1751,1756,1762,2286,2291,2296],{"type":23,"tag":24,"props":25,"children":26},"element","p",{},[27],{"type":28,"value":10},"text",{"type":23,"tag":30,"props":31,"children":32},"ul",{},[33,48],{"type":23,"tag":34,"props":35,"children":36},"li",{},[37,46],{"type":23,"tag":38,"props":39,"children":43},"a",{"href":40,"rel":41},"http://support.apple.com/kb/HT4175",[42],"nofollow",[44],{"type":28,"value":45},"iOS-level data protection",{"type":28,"value":47}," based on the device passcode",{"type":23,"tag":34,"props":49,"children":50},{},[51,53,60],{"type":28,"value":52},"open source projects like ",{"type":23,"tag":38,"props":54,"children":57},{"href":55,"rel":56},"http://sqlcipher.net/ios-tutorial/",[42],[58],{"type":28,"value":59},"SQLCipher for iOS",{"type":28,"value":61}," that encrypt the database file",{"type":23,"tag":24,"props":63,"children":64},{},[65],{"type":28,"value":66},"However, neither of these options is sufficient for if you need to use multiple encryption keys, encrypt only certain attributes, or preserve decrypted data while the device is locked.",{"type":23,"tag":68,"props":69,"children":71},"h2",{"id":70},"encryption-transformer-class",[72],{"type":28,"value":73},"Encryption Transformer Class",{"type":23,"tag":24,"props":75,"children":76},{},[77,79,86,88,95],{"type":28,"value":78},"Instead, it's fairly simple and straight-forward to perform lazy decryption on only certain database fields using the special ",{"type":23,"tag":38,"props":80,"children":83},{"href":81,"rel":82},"https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html",[42],[84],{"type":28,"value":85},"Transformable Core Data attribute type",{"type":28,"value":87},". Transformable attributes are configured with an ",{"type":23,"tag":38,"props":89,"children":92},{"href":90,"rel":91},"http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSValueTransformer_Class/Reference/Reference.html",[42],[93],{"type":28,"value":94},"NSValueTransformer",{"type":28,"value":96}," subclass that you write that specifies:",{"type":23,"tag":30,"props":98,"children":99},{},[100,105,110],{"type":23,"tag":34,"props":101,"children":102},{},[103],{"type":28,"value":104},"a method for converting one object into another",{"type":23,"tag":34,"props":106,"children":107},{},[108],{"type":28,"value":109},"an optional method for reversing that process (and whether reversing is supported)",{"type":23,"tag":34,"props":111,"children":112},{},[113],{"type":28,"value":114},"the class of an object after transformation",{"type":23,"tag":24,"props":116,"children":117},{},[118,120,126,128,133],{"type":28,"value":119},"Here's an example class that converts from a decrypted NSData object to an encrypted one. It relies on a ",{"type":23,"tag":121,"props":122,"children":123},"strong",{},[124],{"type":28,"value":125},"key",{"type":28,"value":127}," method to get the encryption key, and a couple ",{"type":23,"tag":121,"props":129,"children":130},{},[131],{"type":28,"value":132},"NSData",{"type":28,"value":134}," category methods that perform AES-256 encryption and decryption.",{"type":23,"tag":136,"props":137,"children":139},"h3",{"id":138},"encryptiontransformerh",[140],{"type":28,"value":141},"EncryptionTransformer.h",{"type":23,"tag":143,"props":144,"children":148},"pre",{"className":145,"code":146,"language":147,"meta":8,"style":8},"language-objc shiki shiki-themes github-light github-dark","@interface EncryptionTransformer : NSValueTransformer\n{}\n\n/**\n * Returns the key used for encrypting / decrypting values during transformation.\n */\n- (NSString*)key;\n\n@end\n","objc",[149],{"type":23,"tag":150,"props":151,"children":152},"code",{"__ignoreMap":8},[153,182,191,201,211,220,229,263,271],{"type":23,"tag":154,"props":155,"children":158},"span",{"class":156,"line":157},"line",1,[159,165,171,177],{"type":23,"tag":154,"props":160,"children":162},{"style":161},"--shiki-default:#D73A49;--shiki-dark:#F97583",[163],{"type":28,"value":164},"@interface",{"type":23,"tag":154,"props":166,"children":168},{"style":167},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[169],{"type":28,"value":170}," EncryptionTransformer",{"type":23,"tag":154,"props":172,"children":174},{"style":173},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[175],{"type":28,"value":176}," : ",{"type":23,"tag":154,"props":178,"children":179},{"style":167},[180],{"type":28,"value":181},"NSValueTransformer\n",{"type":23,"tag":154,"props":183,"children":185},{"class":156,"line":184},2,[186],{"type":23,"tag":154,"props":187,"children":188},{"style":173},[189],{"type":28,"value":190},"{}\n",{"type":23,"tag":154,"props":192,"children":194},{"class":156,"line":193},3,[195],{"type":23,"tag":154,"props":196,"children":198},{"emptyLinePlaceholder":197},true,[199],{"type":28,"value":200},"\n",{"type":23,"tag":154,"props":202,"children":204},{"class":156,"line":203},4,[205],{"type":23,"tag":154,"props":206,"children":208},{"style":207},"--shiki-default:#6A737D;--shiki-dark:#6A737D",[209],{"type":28,"value":210},"/**\n",{"type":23,"tag":154,"props":212,"children":214},{"class":156,"line":213},5,[215],{"type":23,"tag":154,"props":216,"children":217},{"style":207},[218],{"type":28,"value":219}," * Returns the key used for encrypting / decrypting values during transformation.\n",{"type":23,"tag":154,"props":221,"children":223},{"class":156,"line":222},6,[224],{"type":23,"tag":154,"props":225,"children":226},{"style":207},[227],{"type":28,"value":228}," */\n",{"type":23,"tag":154,"props":230,"children":232},{"class":156,"line":231},7,[233,238,244,249,254,258],{"type":23,"tag":154,"props":234,"children":235},{"style":173},[236],{"type":28,"value":237},"- (",{"type":23,"tag":154,"props":239,"children":241},{"style":240},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[242],{"type":28,"value":243},"NSString",{"type":23,"tag":154,"props":245,"children":246},{"style":161},[247],{"type":28,"value":248},"*",{"type":23,"tag":154,"props":250,"children":251},{"style":173},[252],{"type":28,"value":253},")",{"type":23,"tag":154,"props":255,"children":256},{"style":167},[257],{"type":28,"value":125},{"type":23,"tag":154,"props":259,"children":260},{"style":173},[261],{"type":28,"value":262},";\n",{"type":23,"tag":154,"props":264,"children":266},{"class":156,"line":265},8,[267],{"type":23,"tag":154,"props":268,"children":269},{"emptyLinePlaceholder":197},[270],{"type":28,"value":200},{"type":23,"tag":154,"props":272,"children":274},{"class":156,"line":273},9,[275],{"type":23,"tag":154,"props":276,"children":277},{"style":161},[278],{"type":28,"value":279},"@end\n",{"type":23,"tag":136,"props":281,"children":283},{"id":282},"encryptiontransformerm",[284],{"type":28,"value":285},"EncryptionTransformer.m",{"type":23,"tag":143,"props":287,"children":289},{"className":145,"code":288,"language":147,"meta":8,"style":8},"@implementation EncryptionTransformer\n\n+ (Class)transformedValueClass\n{\n   return [NSData class];\n}\n\n+ (BOOL)allowsReverseTransformation\n{\n   return YES;\n}\n\n- (NSString*)key\n{\n   // Your version of this class might get this key from the app delegate or elsewhere.\n   return @\"secret key\";\n}\n\n- (id)transformedValue:(NSData*)data\n{\n   // If there's no key (e.g. during a data migration), don't try to transform the data\n   if (nil == [self key])\n   {\n      return data;\n   }\n\n   if (nil == data)\n   {\n      return nil;\n   }\n\n   return [data dataAES256EncryptedWithKey:[self key]];\n}\n\n- (id)reverseTransformedValue:(NSData*)data\n{\n   // If there's no key (e.g. during a data migration), don't try to transform the data\n   if (nil == [self key])\n   {\n      return data;\n   }\n\n   if (nil == data)\n   {\n      return nil;\n   }\n\n   return [data dataAES256DecryptedWithKey:[self key]];\n}\n\n@end\n",[290],{"type":23,"tag":150,"props":291,"children":292},{"__ignoreMap":8},[293,306,313,335,343,370,378,385,406,413,430,438,446,471,479,488,506,514,522,562,570,579,622,631,645,654,662,687,695,712,720,728,764,772,780,817,825,833,869,877,889,897,905,929,937,953,961,969,1002,1010,1018],{"type":23,"tag":154,"props":294,"children":295},{"class":156,"line":157},[296,301],{"type":23,"tag":154,"props":297,"children":298},{"style":161},[299],{"type":28,"value":300},"@implementation",{"type":23,"tag":154,"props":302,"children":303},{"style":167},[304],{"type":28,"value":305}," EncryptionTransformer\n",{"type":23,"tag":154,"props":307,"children":308},{"class":156,"line":184},[309],{"type":23,"tag":154,"props":310,"children":311},{"emptyLinePlaceholder":197},[312],{"type":28,"value":200},{"type":23,"tag":154,"props":314,"children":315},{"class":156,"line":193},[316,321,326,330],{"type":23,"tag":154,"props":317,"children":318},{"style":173},[319],{"type":28,"value":320},"+ (",{"type":23,"tag":154,"props":322,"children":323},{"style":161},[324],{"type":28,"value":325},"Class",{"type":23,"tag":154,"props":327,"children":328},{"style":173},[329],{"type":28,"value":253},{"type":23,"tag":154,"props":331,"children":332},{"style":167},[333],{"type":28,"value":334},"transformedValueClass\n",{"type":23,"tag":154,"props":336,"children":337},{"class":156,"line":203},[338],{"type":23,"tag":154,"props":339,"children":340},{"style":173},[341],{"type":28,"value":342},"{\n",{"type":23,"tag":154,"props":344,"children":345},{"class":156,"line":213},[346,351,356,360,365],{"type":23,"tag":154,"props":347,"children":348},{"style":161},[349],{"type":28,"value":350},"   return",{"type":23,"tag":154,"props":352,"children":353},{"style":173},[354],{"type":28,"value":355}," [",{"type":23,"tag":154,"props":357,"children":358},{"style":240},[359],{"type":28,"value":132},{"type":23,"tag":154,"props":361,"children":362},{"style":240},[363],{"type":28,"value":364}," class",{"type":23,"tag":154,"props":366,"children":367},{"style":173},[368],{"type":28,"value":369},"];\n",{"type":23,"tag":154,"props":371,"children":372},{"class":156,"line":222},[373],{"type":23,"tag":154,"props":374,"children":375},{"style":173},[376],{"type":28,"value":377},"}\n",{"type":23,"tag":154,"props":379,"children":380},{"class":156,"line":231},[381],{"type":23,"tag":154,"props":382,"children":383},{"emptyLinePlaceholder":197},[384],{"type":28,"value":200},{"type":23,"tag":154,"props":386,"children":387},{"class":156,"line":265},[388,392,397,401],{"type":23,"tag":154,"props":389,"children":390},{"style":173},[391],{"type":28,"value":320},{"type":23,"tag":154,"props":393,"children":394},{"style":161},[395],{"type":28,"value":396},"BOOL",{"type":23,"tag":154,"props":398,"children":399},{"style":173},[400],{"type":28,"value":253},{"type":23,"tag":154,"props":402,"children":403},{"style":167},[404],{"type":28,"value":405},"allowsReverseTransformation\n",{"type":23,"tag":154,"props":407,"children":408},{"class":156,"line":273},[409],{"type":23,"tag":154,"props":410,"children":411},{"style":173},[412],{"type":28,"value":342},{"type":23,"tag":154,"props":414,"children":416},{"class":156,"line":415},10,[417,421,426],{"type":23,"tag":154,"props":418,"children":419},{"style":161},[420],{"type":28,"value":350},{"type":23,"tag":154,"props":422,"children":423},{"style":240},[424],{"type":28,"value":425}," YES",{"type":23,"tag":154,"props":427,"children":428},{"style":173},[429],{"type":28,"value":262},{"type":23,"tag":154,"props":431,"children":433},{"class":156,"line":432},11,[434],{"type":23,"tag":154,"props":435,"children":436},{"style":173},[437],{"type":28,"value":377},{"type":23,"tag":154,"props":439,"children":441},{"class":156,"line":440},12,[442],{"type":23,"tag":154,"props":443,"children":444},{"emptyLinePlaceholder":197},[445],{"type":28,"value":200},{"type":23,"tag":154,"props":447,"children":449},{"class":156,"line":448},13,[450,454,458,462,466],{"type":23,"tag":154,"props":451,"children":452},{"style":173},[453],{"type":28,"value":237},{"type":23,"tag":154,"props":455,"children":456},{"style":240},[457],{"type":28,"value":243},{"type":23,"tag":154,"props":459,"children":460},{"style":161},[461],{"type":28,"value":248},{"type":23,"tag":154,"props":463,"children":464},{"style":173},[465],{"type":28,"value":253},{"type":23,"tag":154,"props":467,"children":468},{"style":167},[469],{"type":28,"value":470},"key\n",{"type":23,"tag":154,"props":472,"children":474},{"class":156,"line":473},14,[475],{"type":23,"tag":154,"props":476,"children":477},{"style":173},[478],{"type":28,"value":342},{"type":23,"tag":154,"props":480,"children":482},{"class":156,"line":481},15,[483],{"type":23,"tag":154,"props":484,"children":485},{"style":207},[486],{"type":28,"value":487},"   // Your version of this class might get this key from the app delegate or elsewhere.\n",{"type":23,"tag":154,"props":489,"children":491},{"class":156,"line":490},16,[492,496,502],{"type":23,"tag":154,"props":493,"children":494},{"style":161},[495],{"type":28,"value":350},{"type":23,"tag":154,"props":497,"children":499},{"style":498},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[500],{"type":28,"value":501}," @\"secret key\"",{"type":23,"tag":154,"props":503,"children":504},{"style":173},[505],{"type":28,"value":262},{"type":23,"tag":154,"props":507,"children":509},{"class":156,"line":508},17,[510],{"type":23,"tag":154,"props":511,"children":512},{"style":173},[513],{"type":28,"value":377},{"type":23,"tag":154,"props":515,"children":517},{"class":156,"line":516},18,[518],{"type":23,"tag":154,"props":519,"children":520},{"emptyLinePlaceholder":197},[521],{"type":28,"value":200},{"type":23,"tag":154,"props":523,"children":525},{"class":156,"line":524},19,[526,530,535,539,544,549,553,557],{"type":23,"tag":154,"props":527,"children":528},{"style":173},[529],{"type":28,"value":237},{"type":23,"tag":154,"props":531,"children":532},{"style":161},[533],{"type":28,"value":534},"id",{"type":23,"tag":154,"props":536,"children":537},{"style":173},[538],{"type":28,"value":253},{"type":23,"tag":154,"props":540,"children":541},{"style":167},[542],{"type":28,"value":543},"transformedValue:",{"type":23,"tag":154,"props":545,"children":546},{"style":173},[547],{"type":28,"value":548},"(",{"type":23,"tag":154,"props":550,"children":551},{"style":240},[552],{"type":28,"value":132},{"type":23,"tag":154,"props":554,"children":555},{"style":161},[556],{"type":28,"value":248},{"type":23,"tag":154,"props":558,"children":559},{"style":173},[560],{"type":28,"value":561},")data\n",{"type":23,"tag":154,"props":563,"children":565},{"class":156,"line":564},20,[566],{"type":23,"tag":154,"props":567,"children":568},{"style":173},[569],{"type":28,"value":342},{"type":23,"tag":154,"props":571,"children":573},{"class":156,"line":572},21,[574],{"type":23,"tag":154,"props":575,"children":576},{"style":207},[577],{"type":28,"value":578},"   // If there's no key (e.g. during a data migration), don't try to transform the data\n",{"type":23,"tag":154,"props":580,"children":582},{"class":156,"line":581},22,[583,588,593,598,603,607,612,617],{"type":23,"tag":154,"props":584,"children":585},{"style":161},[586],{"type":28,"value":587},"   if",{"type":23,"tag":154,"props":589,"children":590},{"style":173},[591],{"type":28,"value":592}," (",{"type":23,"tag":154,"props":594,"children":595},{"style":240},[596],{"type":28,"value":597},"nil",{"type":23,"tag":154,"props":599,"children":600},{"style":161},[601],{"type":28,"value":602}," ==",{"type":23,"tag":154,"props":604,"children":605},{"style":173},[606],{"type":28,"value":355},{"type":23,"tag":154,"props":608,"children":609},{"style":240},[610],{"type":28,"value":611},"self",{"type":23,"tag":154,"props":613,"children":614},{"style":240},[615],{"type":28,"value":616}," key",{"type":23,"tag":154,"props":618,"children":619},{"style":173},[620],{"type":28,"value":621},"])\n",{"type":23,"tag":154,"props":623,"children":625},{"class":156,"line":624},23,[626],{"type":23,"tag":154,"props":627,"children":628},{"style":173},[629],{"type":28,"value":630},"   {\n",{"type":23,"tag":154,"props":632,"children":634},{"class":156,"line":633},24,[635,640],{"type":23,"tag":154,"props":636,"children":637},{"style":161},[638],{"type":28,"value":639},"      return",{"type":23,"tag":154,"props":641,"children":642},{"style":173},[643],{"type":28,"value":644}," data;\n",{"type":23,"tag":154,"props":646,"children":648},{"class":156,"line":647},25,[649],{"type":23,"tag":154,"props":650,"children":651},{"style":173},[652],{"type":28,"value":653},"   }\n",{"type":23,"tag":154,"props":655,"children":657},{"class":156,"line":656},26,[658],{"type":23,"tag":154,"props":659,"children":660},{"emptyLinePlaceholder":197},[661],{"type":28,"value":200},{"type":23,"tag":154,"props":663,"children":665},{"class":156,"line":664},27,[666,670,674,678,682],{"type":23,"tag":154,"props":667,"children":668},{"style":161},[669],{"type":28,"value":587},{"type":23,"tag":154,"props":671,"children":672},{"style":173},[673],{"type":28,"value":592},{"type":23,"tag":154,"props":675,"children":676},{"style":240},[677],{"type":28,"value":597},{"type":23,"tag":154,"props":679,"children":680},{"style":161},[681],{"type":28,"value":602},{"type":23,"tag":154,"props":683,"children":684},{"style":173},[685],{"type":28,"value":686}," data)\n",{"type":23,"tag":154,"props":688,"children":690},{"class":156,"line":689},28,[691],{"type":23,"tag":154,"props":692,"children":693},{"style":173},[694],{"type":28,"value":630},{"type":23,"tag":154,"props":696,"children":698},{"class":156,"line":697},29,[699,703,708],{"type":23,"tag":154,"props":700,"children":701},{"style":161},[702],{"type":28,"value":639},{"type":23,"tag":154,"props":704,"children":705},{"style":240},[706],{"type":28,"value":707}," nil",{"type":23,"tag":154,"props":709,"children":710},{"style":173},[711],{"type":28,"value":262},{"type":23,"tag":154,"props":713,"children":715},{"class":156,"line":714},30,[716],{"type":23,"tag":154,"props":717,"children":718},{"style":173},[719],{"type":28,"value":653},{"type":23,"tag":154,"props":721,"children":723},{"class":156,"line":722},31,[724],{"type":23,"tag":154,"props":725,"children":726},{"emptyLinePlaceholder":197},[727],{"type":28,"value":200},{"type":23,"tag":154,"props":729,"children":731},{"class":156,"line":730},32,[732,736,741,746,751,755,759],{"type":23,"tag":154,"props":733,"children":734},{"style":161},[735],{"type":28,"value":350},{"type":23,"tag":154,"props":737,"children":738},{"style":173},[739],{"type":28,"value":740}," [data ",{"type":23,"tag":154,"props":742,"children":743},{"style":240},[744],{"type":28,"value":745},"dataAES256EncryptedWithKey:",{"type":23,"tag":154,"props":747,"children":748},{"style":173},[749],{"type":28,"value":750},"[",{"type":23,"tag":154,"props":752,"children":753},{"style":240},[754],{"type":28,"value":611},{"type":23,"tag":154,"props":756,"children":757},{"style":240},[758],{"type":28,"value":616},{"type":23,"tag":154,"props":760,"children":761},{"style":173},[762],{"type":28,"value":763},"]];\n",{"type":23,"tag":154,"props":765,"children":767},{"class":156,"line":766},33,[768],{"type":23,"tag":154,"props":769,"children":770},{"style":173},[771],{"type":28,"value":377},{"type":23,"tag":154,"props":773,"children":775},{"class":156,"line":774},34,[776],{"type":23,"tag":154,"props":777,"children":778},{"emptyLinePlaceholder":197},[779],{"type":28,"value":200},{"type":23,"tag":154,"props":781,"children":783},{"class":156,"line":782},35,[784,788,792,796,801,805,809,813],{"type":23,"tag":154,"props":785,"children":786},{"style":173},[787],{"type":28,"value":237},{"type":23,"tag":154,"props":789,"children":790},{"style":161},[791],{"type":28,"value":534},{"type":23,"tag":154,"props":793,"children":794},{"style":173},[795],{"type":28,"value":253},{"type":23,"tag":154,"props":797,"children":798},{"style":167},[799],{"type":28,"value":800},"reverseTransformedValue:",{"type":23,"tag":154,"props":802,"children":803},{"style":173},[804],{"type":28,"value":548},{"type":23,"tag":154,"props":806,"children":807},{"style":240},[808],{"type":28,"value":132},{"type":23,"tag":154,"props":810,"children":811},{"style":161},[812],{"type":28,"value":248},{"type":23,"tag":154,"props":814,"children":815},{"style":173},[816],{"type":28,"value":561},{"type":23,"tag":154,"props":818,"children":820},{"class":156,"line":819},36,[821],{"type":23,"tag":154,"props":822,"children":823},{"style":173},[824],{"type":28,"value":342},{"type":23,"tag":154,"props":826,"children":828},{"class":156,"line":827},37,[829],{"type":23,"tag":154,"props":830,"children":831},{"style":207},[832],{"type":28,"value":578},{"type":23,"tag":154,"props":834,"children":836},{"class":156,"line":835},38,[837,841,845,849,853,857,861,865],{"type":23,"tag":154,"props":838,"children":839},{"style":161},[840],{"type":28,"value":587},{"type":23,"tag":154,"props":842,"children":843},{"style":173},[844],{"type":28,"value":592},{"type":23,"tag":154,"props":846,"children":847},{"style":240},[848],{"type":28,"value":597},{"type":23,"tag":154,"props":850,"children":851},{"style":161},[852],{"type":28,"value":602},{"type":23,"tag":154,"props":854,"children":855},{"style":173},[856],{"type":28,"value":355},{"type":23,"tag":154,"props":858,"children":859},{"style":240},[860],{"type":28,"value":611},{"type":23,"tag":154,"props":862,"children":863},{"style":240},[864],{"type":28,"value":616},{"type":23,"tag":154,"props":866,"children":867},{"style":173},[868],{"type":28,"value":621},{"type":23,"tag":154,"props":870,"children":872},{"class":156,"line":871},39,[873],{"type":23,"tag":154,"props":874,"children":875},{"style":173},[876],{"type":28,"value":630},{"type":23,"tag":154,"props":878,"children":880},{"class":156,"line":879},40,[881,885],{"type":23,"tag":154,"props":882,"children":883},{"style":161},[884],{"type":28,"value":639},{"type":23,"tag":154,"props":886,"children":887},{"style":173},[888],{"type":28,"value":644},{"type":23,"tag":154,"props":890,"children":892},{"class":156,"line":891},41,[893],{"type":23,"tag":154,"props":894,"children":895},{"style":173},[896],{"type":28,"value":653},{"type":23,"tag":154,"props":898,"children":900},{"class":156,"line":899},42,[901],{"type":23,"tag":154,"props":902,"children":903},{"emptyLinePlaceholder":197},[904],{"type":28,"value":200},{"type":23,"tag":154,"props":906,"children":908},{"class":156,"line":907},43,[909,913,917,921,925],{"type":23,"tag":154,"props":910,"children":911},{"style":161},[912],{"type":28,"value":587},{"type":23,"tag":154,"props":914,"children":915},{"style":173},[916],{"type":28,"value":592},{"type":23,"tag":154,"props":918,"children":919},{"style":240},[920],{"type":28,"value":597},{"type":23,"tag":154,"props":922,"children":923},{"style":161},[924],{"type":28,"value":602},{"type":23,"tag":154,"props":926,"children":927},{"style":173},[928],{"type":28,"value":686},{"type":23,"tag":154,"props":930,"children":932},{"class":156,"line":931},44,[933],{"type":23,"tag":154,"props":934,"children":935},{"style":173},[936],{"type":28,"value":630},{"type":23,"tag":154,"props":938,"children":940},{"class":156,"line":939},45,[941,945,949],{"type":23,"tag":154,"props":942,"children":943},{"style":161},[944],{"type":28,"value":639},{"type":23,"tag":154,"props":946,"children":947},{"style":240},[948],{"type":28,"value":707},{"type":23,"tag":154,"props":950,"children":951},{"style":173},[952],{"type":28,"value":262},{"type":23,"tag":154,"props":954,"children":956},{"class":156,"line":955},46,[957],{"type":23,"tag":154,"props":958,"children":959},{"style":173},[960],{"type":28,"value":653},{"type":23,"tag":154,"props":962,"children":964},{"class":156,"line":963},47,[965],{"type":23,"tag":154,"props":966,"children":967},{"emptyLinePlaceholder":197},[968],{"type":28,"value":200},{"type":23,"tag":154,"props":970,"children":972},{"class":156,"line":971},48,[973,977,981,986,990,994,998],{"type":23,"tag":154,"props":974,"children":975},{"style":161},[976],{"type":28,"value":350},{"type":23,"tag":154,"props":978,"children":979},{"style":173},[980],{"type":28,"value":740},{"type":23,"tag":154,"props":982,"children":983},{"style":240},[984],{"type":28,"value":985},"dataAES256DecryptedWithKey:",{"type":23,"tag":154,"props":987,"children":988},{"style":173},[989],{"type":28,"value":750},{"type":23,"tag":154,"props":991,"children":992},{"style":240},[993],{"type":28,"value":611},{"type":23,"tag":154,"props":995,"children":996},{"style":240},[997],{"type":28,"value":616},{"type":23,"tag":154,"props":999,"children":1000},{"style":173},[1001],{"type":28,"value":763},{"type":23,"tag":154,"props":1003,"children":1005},{"class":156,"line":1004},49,[1006],{"type":23,"tag":154,"props":1007,"children":1008},{"style":173},[1009],{"type":28,"value":377},{"type":23,"tag":154,"props":1011,"children":1013},{"class":156,"line":1012},50,[1014],{"type":23,"tag":154,"props":1015,"children":1016},{"emptyLinePlaceholder":197},[1017],{"type":28,"value":200},{"type":23,"tag":154,"props":1019,"children":1021},{"class":156,"line":1020},51,[1022],{"type":23,"tag":154,"props":1023,"children":1024},{"style":161},[1025],{"type":28,"value":279},{"type":23,"tag":24,"props":1027,"children":1028},{},[1029,1031,1035],{"type":28,"value":1030},"The ",{"type":23,"tag":121,"props":1032,"children":1033},{},[1034],{"type":28,"value":125},{"type":28,"value":1036}," method might get the secret key from any number of places, such as a password requested at login and stored in the app delegate. I'll touch on the NSData category methods that actually perform the encryption in a little bit.",{"type":23,"tag":24,"props":1038,"children":1039},{},[1040],{"type":28,"value":1041},"This encryption class can then easily be subclassed to handle different data types, like strings, dates, numbers, etc. Here's an example string encryption class that converts between NSString and NSData in order to use its parent class transformation methods.",{"type":23,"tag":136,"props":1043,"children":1045},{"id":1044},"encryptiontransformerh-1",[1046],{"type":28,"value":141},{"type":23,"tag":143,"props":1048,"children":1050},{"className":145,"code":1049,"language":147,"meta":8,"style":8},"@interface StringEncryptionTransformer : EncryptionTransformer\n{}\n",[1051],{"type":23,"tag":150,"props":1052,"children":1053},{"__ignoreMap":8},[1054,1075],{"type":23,"tag":154,"props":1055,"children":1056},{"class":156,"line":157},[1057,1061,1066,1070],{"type":23,"tag":154,"props":1058,"children":1059},{"style":161},[1060],{"type":28,"value":164},{"type":23,"tag":154,"props":1062,"children":1063},{"style":167},[1064],{"type":28,"value":1065}," StringEncryptionTransformer",{"type":23,"tag":154,"props":1067,"children":1068},{"style":173},[1069],{"type":28,"value":176},{"type":23,"tag":154,"props":1071,"children":1072},{"style":167},[1073],{"type":28,"value":1074},"EncryptionTransformer\n",{"type":23,"tag":154,"props":1076,"children":1077},{"class":156,"line":184},[1078],{"type":23,"tag":154,"props":1079,"children":1080},{"style":173},[1081],{"type":28,"value":190},{"type":23,"tag":1083,"props":1084,"children":1086},"h4",{"id":1085},"encryptiontransformerm-1",[1087],{"type":28,"value":285},{"type":23,"tag":143,"props":1089,"children":1091},{"className":145,"code":1090,"language":147,"meta":8,"style":8},"@implementation StringEncryptionTransformer\n\n+ (Class)transformedValueClass\n{\n   return [NSString class];\n}\n\n- (id)transformedValue:(NSString*)string\n{\n   NSData* data = [string dataUsingEncoding:NSUTF8StringEncoding];\n   return [super transformedValue:data];\n}\n\n- (id)reverseTransformedValue:(NSData*)data\n{\n   if (nil == data)\n   {\n      return nil;\n   }\n\n   data = [super reverseTransformedValue:data];\n\n   return [[[NSString alloc] initWithBytes:[data bytes]\n                                    length:[data length]\n                                  encoding:NSUTF8StringEncoding]\n           autorelease];\n}\n\n@end\n",[1092],{"type":23,"tag":150,"props":1093,"children":1094},{"__ignoreMap":8},[1095,1107,1114,1133,1140,1163,1170,1177,1213,1220,1256,1282,1289,1296,1331,1338,1361,1368,1383,1390,1397,1426,1433,1479,1500,1512,1520,1527,1534],{"type":23,"tag":154,"props":1096,"children":1097},{"class":156,"line":157},[1098,1102],{"type":23,"tag":154,"props":1099,"children":1100},{"style":161},[1101],{"type":28,"value":300},{"type":23,"tag":154,"props":1103,"children":1104},{"style":167},[1105],{"type":28,"value":1106}," StringEncryptionTransformer\n",{"type":23,"tag":154,"props":1108,"children":1109},{"class":156,"line":184},[1110],{"type":23,"tag":154,"props":1111,"children":1112},{"emptyLinePlaceholder":197},[1113],{"type":28,"value":200},{"type":23,"tag":154,"props":1115,"children":1116},{"class":156,"line":193},[1117,1121,1125,1129],{"type":23,"tag":154,"props":1118,"children":1119},{"style":173},[1120],{"type":28,"value":320},{"type":23,"tag":154,"props":1122,"children":1123},{"style":161},[1124],{"type":28,"value":325},{"type":23,"tag":154,"props":1126,"children":1127},{"style":173},[1128],{"type":28,"value":253},{"type":23,"tag":154,"props":1130,"children":1131},{"style":167},[1132],{"type":28,"value":334},{"type":23,"tag":154,"props":1134,"children":1135},{"class":156,"line":203},[1136],{"type":23,"tag":154,"props":1137,"children":1138},{"style":173},[1139],{"type":28,"value":342},{"type":23,"tag":154,"props":1141,"children":1142},{"class":156,"line":213},[1143,1147,1151,1155,1159],{"type":23,"tag":154,"props":1144,"children":1145},{"style":161},[1146],{"type":28,"value":350},{"type":23,"tag":154,"props":1148,"children":1149},{"style":173},[1150],{"type":28,"value":355},{"type":23,"tag":154,"props":1152,"children":1153},{"style":240},[1154],{"type":28,"value":243},{"type":23,"tag":154,"props":1156,"children":1157},{"style":240},[1158],{"type":28,"value":364},{"type":23,"tag":154,"props":1160,"children":1161},{"style":173},[1162],{"type":28,"value":369},{"type":23,"tag":154,"props":1164,"children":1165},{"class":156,"line":222},[1166],{"type":23,"tag":154,"props":1167,"children":1168},{"style":173},[1169],{"type":28,"value":377},{"type":23,"tag":154,"props":1171,"children":1172},{"class":156,"line":231},[1173],{"type":23,"tag":154,"props":1174,"children":1175},{"emptyLinePlaceholder":197},[1176],{"type":28,"value":200},{"type":23,"tag":154,"props":1178,"children":1179},{"class":156,"line":265},[1180,1184,1188,1192,1196,1200,1204,1208],{"type":23,"tag":154,"props":1181,"children":1182},{"style":173},[1183],{"type":28,"value":237},{"type":23,"tag":154,"props":1185,"children":1186},{"style":161},[1187],{"type":28,"value":534},{"type":23,"tag":154,"props":1189,"children":1190},{"style":173},[1191],{"type":28,"value":253},{"type":23,"tag":154,"props":1193,"children":1194},{"style":167},[1195],{"type":28,"value":543},{"type":23,"tag":154,"props":1197,"children":1198},{"style":173},[1199],{"type":28,"value":548},{"type":23,"tag":154,"props":1201,"children":1202},{"style":240},[1203],{"type":28,"value":243},{"type":23,"tag":154,"props":1205,"children":1206},{"style":161},[1207],{"type":28,"value":248},{"type":23,"tag":154,"props":1209,"children":1210},{"style":173},[1211],{"type":28,"value":1212},")string\n",{"type":23,"tag":154,"props":1214,"children":1215},{"class":156,"line":273},[1216],{"type":23,"tag":154,"props":1217,"children":1218},{"style":173},[1219],{"type":28,"value":342},{"type":23,"tag":154,"props":1221,"children":1222},{"class":156,"line":415},[1223,1228,1232,1237,1242,1247,1252],{"type":23,"tag":154,"props":1224,"children":1225},{"style":240},[1226],{"type":28,"value":1227},"   NSData",{"type":23,"tag":154,"props":1229,"children":1230},{"style":161},[1231],{"type":28,"value":248},{"type":23,"tag":154,"props":1233,"children":1234},{"style":173},[1235],{"type":28,"value":1236}," data ",{"type":23,"tag":154,"props":1238,"children":1239},{"style":161},[1240],{"type":28,"value":1241},"=",{"type":23,"tag":154,"props":1243,"children":1244},{"style":173},[1245],{"type":28,"value":1246}," [string ",{"type":23,"tag":154,"props":1248,"children":1249},{"style":240},[1250],{"type":28,"value":1251},"dataUsingEncoding:NSUTF8StringEncoding",{"type":23,"tag":154,"props":1253,"children":1254},{"style":173},[1255],{"type":28,"value":369},{"type":23,"tag":154,"props":1257,"children":1258},{"class":156,"line":432},[1259,1263,1267,1272,1277],{"type":23,"tag":154,"props":1260,"children":1261},{"style":161},[1262],{"type":28,"value":350},{"type":23,"tag":154,"props":1264,"children":1265},{"style":173},[1266],{"type":28,"value":355},{"type":23,"tag":154,"props":1268,"children":1269},{"style":240},[1270],{"type":28,"value":1271},"super",{"type":23,"tag":154,"props":1273,"children":1274},{"style":240},[1275],{"type":28,"value":1276}," transformedValue:",{"type":23,"tag":154,"props":1278,"children":1279},{"style":173},[1280],{"type":28,"value":1281},"data];\n",{"type":23,"tag":154,"props":1283,"children":1284},{"class":156,"line":440},[1285],{"type":23,"tag":154,"props":1286,"children":1287},{"style":173},[1288],{"type":28,"value":377},{"type":23,"tag":154,"props":1290,"children":1291},{"class":156,"line":448},[1292],{"type":23,"tag":154,"props":1293,"children":1294},{"emptyLinePlaceholder":197},[1295],{"type":28,"value":200},{"type":23,"tag":154,"props":1297,"children":1298},{"class":156,"line":473},[1299,1303,1307,1311,1315,1319,1323,1327],{"type":23,"tag":154,"props":1300,"children":1301},{"style":173},[1302],{"type":28,"value":237},{"type":23,"tag":154,"props":1304,"children":1305},{"style":161},[1306],{"type":28,"value":534},{"type":23,"tag":154,"props":1308,"children":1309},{"style":173},[1310],{"type":28,"value":253},{"type":23,"tag":154,"props":1312,"children":1313},{"style":167},[1314],{"type":28,"value":800},{"type":23,"tag":154,"props":1316,"children":1317},{"style":173},[1318],{"type":28,"value":548},{"type":23,"tag":154,"props":1320,"children":1321},{"style":240},[1322],{"type":28,"value":132},{"type":23,"tag":154,"props":1324,"children":1325},{"style":161},[1326],{"type":28,"value":248},{"type":23,"tag":154,"props":1328,"children":1329},{"style":173},[1330],{"type":28,"value":561},{"type":23,"tag":154,"props":1332,"children":1333},{"class":156,"line":481},[1334],{"type":23,"tag":154,"props":1335,"children":1336},{"style":173},[1337],{"type":28,"value":342},{"type":23,"tag":154,"props":1339,"children":1340},{"class":156,"line":490},[1341,1345,1349,1353,1357],{"type":23,"tag":154,"props":1342,"children":1343},{"style":161},[1344],{"type":28,"value":587},{"type":23,"tag":154,"props":1346,"children":1347},{"style":173},[1348],{"type":28,"value":592},{"type":23,"tag":154,"props":1350,"children":1351},{"style":240},[1352],{"type":28,"value":597},{"type":23,"tag":154,"props":1354,"children":1355},{"style":161},[1356],{"type":28,"value":602},{"type":23,"tag":154,"props":1358,"children":1359},{"style":173},[1360],{"type":28,"value":686},{"type":23,"tag":154,"props":1362,"children":1363},{"class":156,"line":508},[1364],{"type":23,"tag":154,"props":1365,"children":1366},{"style":173},[1367],{"type":28,"value":630},{"type":23,"tag":154,"props":1369,"children":1370},{"class":156,"line":516},[1371,1375,1379],{"type":23,"tag":154,"props":1372,"children":1373},{"style":161},[1374],{"type":28,"value":639},{"type":23,"tag":154,"props":1376,"children":1377},{"style":240},[1378],{"type":28,"value":707},{"type":23,"tag":154,"props":1380,"children":1381},{"style":173},[1382],{"type":28,"value":262},{"type":23,"tag":154,"props":1384,"children":1385},{"class":156,"line":524},[1386],{"type":23,"tag":154,"props":1387,"children":1388},{"style":173},[1389],{"type":28,"value":653},{"type":23,"tag":154,"props":1391,"children":1392},{"class":156,"line":564},[1393],{"type":23,"tag":154,"props":1394,"children":1395},{"emptyLinePlaceholder":197},[1396],{"type":28,"value":200},{"type":23,"tag":154,"props":1398,"children":1399},{"class":156,"line":572},[1400,1405,1409,1413,1417,1422],{"type":23,"tag":154,"props":1401,"children":1402},{"style":173},[1403],{"type":28,"value":1404},"   data ",{"type":23,"tag":154,"props":1406,"children":1407},{"style":161},[1408],{"type":28,"value":1241},{"type":23,"tag":154,"props":1410,"children":1411},{"style":173},[1412],{"type":28,"value":355},{"type":23,"tag":154,"props":1414,"children":1415},{"style":240},[1416],{"type":28,"value":1271},{"type":23,"tag":154,"props":1418,"children":1419},{"style":240},[1420],{"type":28,"value":1421}," reverseTransformedValue:",{"type":23,"tag":154,"props":1423,"children":1424},{"style":173},[1425],{"type":28,"value":1281},{"type":23,"tag":154,"props":1427,"children":1428},{"class":156,"line":581},[1429],{"type":23,"tag":154,"props":1430,"children":1431},{"emptyLinePlaceholder":197},[1432],{"type":28,"value":200},{"type":23,"tag":154,"props":1434,"children":1435},{"class":156,"line":624},[1436,1440,1445,1449,1454,1459,1464,1469,1474],{"type":23,"tag":154,"props":1437,"children":1438},{"style":161},[1439],{"type":28,"value":350},{"type":23,"tag":154,"props":1441,"children":1442},{"style":173},[1443],{"type":28,"value":1444}," [[[",{"type":23,"tag":154,"props":1446,"children":1447},{"style":240},[1448],{"type":28,"value":243},{"type":23,"tag":154,"props":1450,"children":1451},{"style":240},[1452],{"type":28,"value":1453}," alloc",{"type":23,"tag":154,"props":1455,"children":1456},{"style":173},[1457],{"type":28,"value":1458},"] ",{"type":23,"tag":154,"props":1460,"children":1461},{"style":240},[1462],{"type":28,"value":1463},"initWithBytes:",{"type":23,"tag":154,"props":1465,"children":1466},{"style":173},[1467],{"type":28,"value":1468},"[data ",{"type":23,"tag":154,"props":1470,"children":1471},{"style":240},[1472],{"type":28,"value":1473},"bytes",{"type":23,"tag":154,"props":1475,"children":1476},{"style":173},[1477],{"type":28,"value":1478},"]\n",{"type":23,"tag":154,"props":1480,"children":1481},{"class":156,"line":633},[1482,1487,1491,1496],{"type":23,"tag":154,"props":1483,"children":1484},{"style":240},[1485],{"type":28,"value":1486},"                                    length:",{"type":23,"tag":154,"props":1488,"children":1489},{"style":173},[1490],{"type":28,"value":1468},{"type":23,"tag":154,"props":1492,"children":1493},{"style":240},[1494],{"type":28,"value":1495},"length",{"type":23,"tag":154,"props":1497,"children":1498},{"style":173},[1499],{"type":28,"value":1478},{"type":23,"tag":154,"props":1501,"children":1502},{"class":156,"line":647},[1503,1508],{"type":23,"tag":154,"props":1504,"children":1505},{"style":240},[1506],{"type":28,"value":1507},"                                  encoding:NSUTF8StringEncoding",{"type":23,"tag":154,"props":1509,"children":1510},{"style":173},[1511],{"type":28,"value":1478},{"type":23,"tag":154,"props":1513,"children":1514},{"class":156,"line":656},[1515],{"type":23,"tag":154,"props":1516,"children":1517},{"style":173},[1518],{"type":28,"value":1519},"           autorelease];\n",{"type":23,"tag":154,"props":1521,"children":1522},{"class":156,"line":664},[1523],{"type":23,"tag":154,"props":1524,"children":1525},{"style":173},[1526],{"type":28,"value":377},{"type":23,"tag":154,"props":1528,"children":1529},{"class":156,"line":689},[1530],{"type":23,"tag":154,"props":1531,"children":1532},{"emptyLinePlaceholder":197},[1533],{"type":28,"value":200},{"type":23,"tag":154,"props":1535,"children":1536},{"class":156,"line":697},[1537],{"type":23,"tag":154,"props":1538,"children":1539},{"style":161},[1540],{"type":28,"value":279},{"type":23,"tag":24,"props":1542,"children":1543},{},[1544,1546,1552,1554,1559,1561,1566,1568,1573],{"type":28,"value":1545},"Once these classes are set up, the Core Data model editor lets you assign an entity ",{"type":23,"tag":1547,"props":1548,"children":1549},"em",{},[1550],{"type":28,"value":1551},"attribute type",{"type":28,"value":1553}," of ",{"type":23,"tag":121,"props":1555,"children":1556},{},[1557],{"type":28,"value":1558},"Transformable",{"type":28,"value":1560}," and a ",{"type":23,"tag":1547,"props":1562,"children":1563},{},[1564],{"type":28,"value":1565},"name",{"type":28,"value":1567}," of the NSValueTransformer class, such as ",{"type":23,"tag":121,"props":1569,"children":1570},{},[1571],{"type":28,"value":1572},"StringEncryptionTransformer",{"type":28,"value":1574},".",{"type":23,"tag":24,"props":1576,"children":1577},{},[1578,1584],{"type":23,"tag":1579,"props":1580,"children":1583},"img",{"alt":8,"src":1581,"title":1582},"/nharrison/2012-07/img/core-data-editor1.png","Core Data editor",[],{"type":28,"value":1585}," Core Data model editor in Xcode showing an entity's Transformable attribute.",{"type":23,"tag":24,"props":1587,"children":1588},{},[1589,1591,1597],{"type":28,"value":1590},"Now, these attributes can be written to in code just like any other (e.g. ",{"type":23,"tag":150,"props":1592,"children":1594},{"className":1593},[],[1595],{"type":28,"value":1596},"clark.secretIdentity = @\"superman\"",{"type":28,"value":1598},"), but when they are persisted to the underlying SQLite database (or other sort of data store), the appropriate NSValueTransformer class will be called to encrypt the values before writing them to the data store.",{"type":23,"tag":24,"props":1600,"children":1601},{},[1602],{"type":28,"value":1603},"Likewise, at the time a persisted object is read from the data store, the NSValueTransformer class will decrypt it. Encryption and decryption is thus lazy and only performed when an object is used or updated -- no need to decrypt an entire file or database during app startup.",{"type":23,"tag":68,"props":1605,"children":1607},{"id":1606},"aes-256-encryption-category",[1608],{"type":28,"value":1609},"AES-256 encryption category",{"type":23,"tag":24,"props":1611,"children":1612},{},[1613,1615,1622,1624,1631,1633,1640],{"type":28,"value":1614},"There are a number of example classes that make performing ",{"type":23,"tag":38,"props":1616,"children":1619},{"href":1617,"rel":1618},"http://en.wikipedia.org/wiki/Advanced_Encryption_Standard",[42],[1620],{"type":28,"value":1621},"AES-256",{"type":28,"value":1623}," encryption as simple as shown above, such as Jim Dovey's ",{"type":23,"tag":38,"props":1625,"children":1628},{"href":1626,"rel":1627},"https://github.com/AlanQuatermain/aqtoolkit/tree/master/CommonCrypto",[42],[1629],{"type":28,"value":1630},"NSData+CommonCrypto category",{"type":28,"value":1632}," and this ",{"type":23,"tag":38,"props":1634,"children":1637},{"href":1635,"rel":1636},"http://pastie.org/426530",[42],[1638],{"type":28,"value":1639},"unattributed snippet",{"type":28,"value":1641},".  The better ones use encryption libraries provided by Apple, which may (or may not, IANAL) mean that you don't need a CCATS form for app submission.",{"type":23,"tag":24,"props":1643,"children":1644},{},[1645,1647,1653,1655,1661,1663,1669,1671,1678],{"type":28,"value":1646},"However, one major caveat to encrypting attributes individually is that patterns from short, repeated values will naturally rise.  If you are encrypting only a couple different possible values for an attribute (e.g. \"superhero\" and \"evildoer\"), simple encryption using the same key will result in only two encrypted values.  That is, for the key \"",{"type":23,"tag":150,"props":1648,"children":1650},{"className":1649},[],[1651],{"type":28,"value":1652},"top secret",{"type":28,"value":1654},"\", the value \"",{"type":23,"tag":150,"props":1656,"children":1658},{"className":1657},[],[1659],{"type":28,"value":1660},"Superman",{"type":28,"value":1662},"\" will always encrypt to \"",{"type":23,"tag":150,"props":1664,"children":1666},{"className":1665},[],[1667],{"type":28,"value":1668},"?b64JzJ4aC0IhKaf7xeTWaglC6L/3VFxwA5XVrfDRntxebO4rFUSdNNrzfVFIU3yZH0F?64b",{"type":28,"value":1670},"\" (",{"type":23,"tag":38,"props":1672,"children":1675},{"href":1673,"rel":1674},"http://www.fourmilab.ch/javascrypt/javascrypt.html",[42],[1676],{"type":28,"value":1677},"Javascrypt",{"type":28,"value":1679}," is a handy online tool for encryption).",{"type":23,"tag":24,"props":1681,"children":1682},{},[1683,1685,1695,1697,1704],{"type":28,"value":1684},"Enter the ",{"type":23,"tag":38,"props":1686,"children":1689},{"href":1687,"rel":1688},"http://en.wikipedia.org/wiki/Initialization_vector",[42],[1690],{"type":23,"tag":121,"props":1691,"children":1692},{},[1693],{"type":28,"value":1694},"initialization vector",{"type":28,"value":1696}," (IV), which like the ",{"type":23,"tag":38,"props":1698,"children":1701},{"href":1699,"rel":1700},"http://en.wikipedia.org/wiki/Salt_%28cryptography%29",[42],[1702],{"type":28,"value":1703},"salt",{"type":28,"value":1705}," for a password helps hide patterns by randomizing encryption input.  The IV should be:",{"type":23,"tag":1707,"props":1708,"children":1709},"ol",{},[1710,1722,1727,1732],{"type":23,"tag":34,"props":1711,"children":1712},{},[1713,1715],{"type":28,"value":1714},"a random number, for example the result of ",{"type":23,"tag":38,"props":1716,"children":1719},{"href":1717,"rel":1718},"https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/arc4random.3.html",[42],[1720],{"type":28,"value":1721},"arc4random()",{"type":23,"tag":34,"props":1723,"children":1724},{},[1725],{"type":28,"value":1726},"different for every attribute, or at least every entity",{"type":23,"tag":34,"props":1728,"children":1729},{},[1730],{"type":28,"value":1731},"stored alongside the encrypted value, since the same IV used for encryption is necessary for decryption",{"type":23,"tag":34,"props":1733,"children":1734},{},[1735],{"type":28,"value":1736},"public, that is it need not (and should not) be encrypted",{"type":23,"tag":24,"props":1738,"children":1739},{},[1740],{"type":28,"value":1741},"Unfortunately, many example code snippets that call CCCrypt (including one linked above) leave the initialization vector parameter as simply:",{"type":23,"tag":24,"props":1743,"children":1744},{},[1745],{"type":23,"tag":150,"props":1746,"children":1748},{"className":1747},[],[1749],{"type":28,"value":1750},"NULL / _initialization vector (optional)_ /,",{"type":23,"tag":24,"props":1752,"children":1753},{},[1754],{"type":28,"value":1755},"Rather than follow suit, it's simple to update our EncryptionTransformer to generate a IV and prepend it to the encrypted data:",{"type":23,"tag":1083,"props":1757,"children":1759},{"id":1758},"encryptiontransformermencryptiontransformerm",[1760],{"type":28,"value":1761},"EncryptionTransformer.mEncryptionTransformer.m",{"type":23,"tag":143,"props":1763,"children":1765},{"className":145,"code":1764,"language":147,"meta":8,"style":8},"- (id)transformedValue:(NSData*)data\n{\n   ...\n\n   // Use another NSData category method (left as an exercise \n   // to the reader) to randomly generate the IV data\n   NSData* iv = [NSData randomDataOfLength:32];\n\n   data = [data dataAES256EncryptedWithKey:[self key] Iv:iv];\n\n   // Return a data object that includes the IV with the \n   // encrypted data appended\n   NSMutableData* mutableData = [NSMutableData dataWithData:iv];\n   [mutableData appendData:data];\n   return mutableData;\n}\n\n- (id)reverseTransformedValue:(NSData*)data\n{\n   ...\n\n   // The IV was stored in the first 32 bytes of the data\n   NSData* iv = [data subdataWithRange:NSMakeRange(0, 32)];\n\n   // Remove the IV from the encrypted data and decrypt it\n   NSMutableData* mutableData = [NSMutableData dataWithData:data];\n   [mutableData replaceBytesInRange:NSMakeRange(0, 32) withBytes:NULL];\n   return [mutableData dataAES256DecryptedWithKey:[self key] Iv:iv];\n}\n",[1766],{"type":23,"tag":150,"props":1767,"children":1768},{"__ignoreMap":8},[1769,1802,1809,1817,1824,1832,1840,1877,1884,1929,1936,1944,1952,1991,2008,2020,2027,2034,2066,2073,2080,2087,2095,2147,2154,2162,2197,2239,2279],{"type":23,"tag":154,"props":1770,"children":1771},{"class":156,"line":157},[1772,1777,1781,1785,1790,1794,1798],{"type":23,"tag":154,"props":1773,"children":1774},{"style":161},[1775],{"type":28,"value":1776},"-",{"type":23,"tag":154,"props":1778,"children":1779},{"style":173},[1780],{"type":28,"value":592},{"type":23,"tag":154,"props":1782,"children":1783},{"style":161},[1784],{"type":28,"value":534},{"type":23,"tag":154,"props":1786,"children":1787},{"style":173},[1788],{"type":28,"value":1789},")transformedValue:(",{"type":23,"tag":154,"props":1791,"children":1792},{"style":240},[1793],{"type":28,"value":132},{"type":23,"tag":154,"props":1795,"children":1796},{"style":161},[1797],{"type":28,"value":248},{"type":23,"tag":154,"props":1799,"children":1800},{"style":173},[1801],{"type":28,"value":561},{"type":23,"tag":154,"props":1803,"children":1804},{"class":156,"line":184},[1805],{"type":23,"tag":154,"props":1806,"children":1807},{"style":173},[1808],{"type":28,"value":342},{"type":23,"tag":154,"props":1810,"children":1811},{"class":156,"line":193},[1812],{"type":23,"tag":154,"props":1813,"children":1814},{"style":173},[1815],{"type":28,"value":1816},"   ...\n",{"type":23,"tag":154,"props":1818,"children":1819},{"class":156,"line":203},[1820],{"type":23,"tag":154,"props":1821,"children":1822},{"emptyLinePlaceholder":197},[1823],{"type":28,"value":200},{"type":23,"tag":154,"props":1825,"children":1826},{"class":156,"line":213},[1827],{"type":23,"tag":154,"props":1828,"children":1829},{"style":207},[1830],{"type":28,"value":1831},"   // Use another NSData category method (left as an exercise \n",{"type":23,"tag":154,"props":1833,"children":1834},{"class":156,"line":222},[1835],{"type":23,"tag":154,"props":1836,"children":1837},{"style":207},[1838],{"type":28,"value":1839},"   // to the reader) to randomly generate the IV data\n",{"type":23,"tag":154,"props":1841,"children":1842},{"class":156,"line":231},[1843,1847,1851,1856,1860,1864,1868,1873],{"type":23,"tag":154,"props":1844,"children":1845},{"style":240},[1846],{"type":28,"value":1227},{"type":23,"tag":154,"props":1848,"children":1849},{"style":161},[1850],{"type":28,"value":248},{"type":23,"tag":154,"props":1852,"children":1853},{"style":173},[1854],{"type":28,"value":1855}," iv ",{"type":23,"tag":154,"props":1857,"children":1858},{"style":161},[1859],{"type":28,"value":1241},{"type":23,"tag":154,"props":1861,"children":1862},{"style":173},[1863],{"type":28,"value":355},{"type":23,"tag":154,"props":1865,"children":1866},{"style":240},[1867],{"type":28,"value":132},{"type":23,"tag":154,"props":1869,"children":1870},{"style":240},[1871],{"type":28,"value":1872}," randomDataOfLength:32",{"type":23,"tag":154,"props":1874,"children":1875},{"style":173},[1876],{"type":28,"value":369},{"type":23,"tag":154,"props":1878,"children":1879},{"class":156,"line":265},[1880],{"type":23,"tag":154,"props":1881,"children":1882},{"emptyLinePlaceholder":197},[1883],{"type":28,"value":200},{"type":23,"tag":154,"props":1885,"children":1886},{"class":156,"line":273},[1887,1891,1895,1899,1903,1907,1911,1915,1919,1924],{"type":23,"tag":154,"props":1888,"children":1889},{"style":173},[1890],{"type":28,"value":1404},{"type":23,"tag":154,"props":1892,"children":1893},{"style":161},[1894],{"type":28,"value":1241},{"type":23,"tag":154,"props":1896,"children":1897},{"style":173},[1898],{"type":28,"value":740},{"type":23,"tag":154,"props":1900,"children":1901},{"style":240},[1902],{"type":28,"value":745},{"type":23,"tag":154,"props":1904,"children":1905},{"style":173},[1906],{"type":28,"value":750},{"type":23,"tag":154,"props":1908,"children":1909},{"style":240},[1910],{"type":28,"value":611},{"type":23,"tag":154,"props":1912,"children":1913},{"style":240},[1914],{"type":28,"value":616},{"type":23,"tag":154,"props":1916,"children":1917},{"style":173},[1918],{"type":28,"value":1458},{"type":23,"tag":154,"props":1920,"children":1921},{"style":240},[1922],{"type":28,"value":1923},"Iv:",{"type":23,"tag":154,"props":1925,"children":1926},{"style":173},[1927],{"type":28,"value":1928},"iv];\n",{"type":23,"tag":154,"props":1930,"children":1931},{"class":156,"line":415},[1932],{"type":23,"tag":154,"props":1933,"children":1934},{"emptyLinePlaceholder":197},[1935],{"type":28,"value":200},{"type":23,"tag":154,"props":1937,"children":1938},{"class":156,"line":432},[1939],{"type":23,"tag":154,"props":1940,"children":1941},{"style":207},[1942],{"type":28,"value":1943},"   // Return a data object that includes the IV with the \n",{"type":23,"tag":154,"props":1945,"children":1946},{"class":156,"line":440},[1947],{"type":23,"tag":154,"props":1948,"children":1949},{"style":207},[1950],{"type":28,"value":1951},"   // encrypted data appended\n",{"type":23,"tag":154,"props":1953,"children":1954},{"class":156,"line":448},[1955,1960,1964,1969,1973,1977,1982,1987],{"type":23,"tag":154,"props":1956,"children":1957},{"style":240},[1958],{"type":28,"value":1959},"   NSMutableData",{"type":23,"tag":154,"props":1961,"children":1962},{"style":161},[1963],{"type":28,"value":248},{"type":23,"tag":154,"props":1965,"children":1966},{"style":173},[1967],{"type":28,"value":1968}," mutableData ",{"type":23,"tag":154,"props":1970,"children":1971},{"style":161},[1972],{"type":28,"value":1241},{"type":23,"tag":154,"props":1974,"children":1975},{"style":173},[1976],{"type":28,"value":355},{"type":23,"tag":154,"props":1978,"children":1979},{"style":240},[1980],{"type":28,"value":1981},"NSMutableData",{"type":23,"tag":154,"props":1983,"children":1984},{"style":240},[1985],{"type":28,"value":1986}," dataWithData:",{"type":23,"tag":154,"props":1988,"children":1989},{"style":173},[1990],{"type":28,"value":1928},{"type":23,"tag":154,"props":1992,"children":1993},{"class":156,"line":473},[1994,1999,2004],{"type":23,"tag":154,"props":1995,"children":1996},{"style":173},[1997],{"type":28,"value":1998},"   [mutableData ",{"type":23,"tag":154,"props":2000,"children":2001},{"style":240},[2002],{"type":28,"value":2003},"appendData:",{"type":23,"tag":154,"props":2005,"children":2006},{"style":173},[2007],{"type":28,"value":1281},{"type":23,"tag":154,"props":2009,"children":2010},{"class":156,"line":481},[2011,2015],{"type":23,"tag":154,"props":2012,"children":2013},{"style":161},[2014],{"type":28,"value":350},{"type":23,"tag":154,"props":2016,"children":2017},{"style":173},[2018],{"type":28,"value":2019}," mutableData;\n",{"type":23,"tag":154,"props":2021,"children":2022},{"class":156,"line":490},[2023],{"type":23,"tag":154,"props":2024,"children":2025},{"style":173},[2026],{"type":28,"value":377},{"type":23,"tag":154,"props":2028,"children":2029},{"class":156,"line":508},[2030],{"type":23,"tag":154,"props":2031,"children":2032},{"emptyLinePlaceholder":197},[2033],{"type":28,"value":200},{"type":23,"tag":154,"props":2035,"children":2036},{"class":156,"line":516},[2037,2041,2045,2049,2054,2058,2062],{"type":23,"tag":154,"props":2038,"children":2039},{"style":161},[2040],{"type":28,"value":1776},{"type":23,"tag":154,"props":2042,"children":2043},{"style":173},[2044],{"type":28,"value":592},{"type":23,"tag":154,"props":2046,"children":2047},{"style":161},[2048],{"type":28,"value":534},{"type":23,"tag":154,"props":2050,"children":2051},{"style":173},[2052],{"type":28,"value":2053},")reverseTransformedValue:(",{"type":23,"tag":154,"props":2055,"children":2056},{"style":240},[2057],{"type":28,"value":132},{"type":23,"tag":154,"props":2059,"children":2060},{"style":161},[2061],{"type":28,"value":248},{"type":23,"tag":154,"props":2063,"children":2064},{"style":173},[2065],{"type":28,"value":561},{"type":23,"tag":154,"props":2067,"children":2068},{"class":156,"line":524},[2069],{"type":23,"tag":154,"props":2070,"children":2071},{"style":173},[2072],{"type":28,"value":342},{"type":23,"tag":154,"props":2074,"children":2075},{"class":156,"line":564},[2076],{"type":23,"tag":154,"props":2077,"children":2078},{"style":173},[2079],{"type":28,"value":1816},{"type":23,"tag":154,"props":2081,"children":2082},{"class":156,"line":572},[2083],{"type":23,"tag":154,"props":2084,"children":2085},{"emptyLinePlaceholder":197},[2086],{"type":28,"value":200},{"type":23,"tag":154,"props":2088,"children":2089},{"class":156,"line":581},[2090],{"type":23,"tag":154,"props":2091,"children":2092},{"style":207},[2093],{"type":28,"value":2094},"   // The IV was stored in the first 32 bytes of the data\n",{"type":23,"tag":154,"props":2096,"children":2097},{"class":156,"line":624},[2098,2102,2106,2110,2114,2118,2123,2127,2132,2137,2142],{"type":23,"tag":154,"props":2099,"children":2100},{"style":240},[2101],{"type":28,"value":1227},{"type":23,"tag":154,"props":2103,"children":2104},{"style":161},[2105],{"type":28,"value":248},{"type":23,"tag":154,"props":2107,"children":2108},{"style":173},[2109],{"type":28,"value":1855},{"type":23,"tag":154,"props":2111,"children":2112},{"style":161},[2113],{"type":28,"value":1241},{"type":23,"tag":154,"props":2115,"children":2116},{"style":173},[2117],{"type":28,"value":740},{"type":23,"tag":154,"props":2119,"children":2120},{"style":240},[2121],{"type":28,"value":2122},"subdataWithRange:NSMakeRange",{"type":23,"tag":154,"props":2124,"children":2125},{"style":173},[2126],{"type":28,"value":548},{"type":23,"tag":154,"props":2128,"children":2129},{"style":240},[2130],{"type":28,"value":2131},"0",{"type":23,"tag":154,"props":2133,"children":2134},{"style":173},[2135],{"type":28,"value":2136},", ",{"type":23,"tag":154,"props":2138,"children":2139},{"style":240},[2140],{"type":28,"value":2141},"32",{"type":23,"tag":154,"props":2143,"children":2144},{"style":173},[2145],{"type":28,"value":2146},")];\n",{"type":23,"tag":154,"props":2148,"children":2149},{"class":156,"line":633},[2150],{"type":23,"tag":154,"props":2151,"children":2152},{"emptyLinePlaceholder":197},[2153],{"type":28,"value":200},{"type":23,"tag":154,"props":2155,"children":2156},{"class":156,"line":647},[2157],{"type":23,"tag":154,"props":2158,"children":2159},{"style":207},[2160],{"type":28,"value":2161},"   // Remove the IV from the encrypted data and decrypt it\n",{"type":23,"tag":154,"props":2163,"children":2164},{"class":156,"line":656},[2165,2169,2173,2177,2181,2185,2189,2193],{"type":23,"tag":154,"props":2166,"children":2167},{"style":240},[2168],{"type":28,"value":1959},{"type":23,"tag":154,"props":2170,"children":2171},{"style":161},[2172],{"type":28,"value":248},{"type":23,"tag":154,"props":2174,"children":2175},{"style":173},[2176],{"type":28,"value":1968},{"type":23,"tag":154,"props":2178,"children":2179},{"style":161},[2180],{"type":28,"value":1241},{"type":23,"tag":154,"props":2182,"children":2183},{"style":173},[2184],{"type":28,"value":355},{"type":23,"tag":154,"props":2186,"children":2187},{"style":240},[2188],{"type":28,"value":1981},{"type":23,"tag":154,"props":2190,"children":2191},{"style":240},[2192],{"type":28,"value":1986},{"type":23,"tag":154,"props":2194,"children":2195},{"style":173},[2196],{"type":28,"value":1281},{"type":23,"tag":154,"props":2198,"children":2199},{"class":156,"line":664},[2200,2204,2209,2213,2217,2221,2225,2230,2235],{"type":23,"tag":154,"props":2201,"children":2202},{"style":173},[2203],{"type":28,"value":1998},{"type":23,"tag":154,"props":2205,"children":2206},{"style":240},[2207],{"type":28,"value":2208},"replaceBytesInRange:NSMakeRange",{"type":23,"tag":154,"props":2210,"children":2211},{"style":173},[2212],{"type":28,"value":548},{"type":23,"tag":154,"props":2214,"children":2215},{"style":240},[2216],{"type":28,"value":2131},{"type":23,"tag":154,"props":2218,"children":2219},{"style":173},[2220],{"type":28,"value":2136},{"type":23,"tag":154,"props":2222,"children":2223},{"style":240},[2224],{"type":28,"value":2141},{"type":23,"tag":154,"props":2226,"children":2227},{"style":173},[2228],{"type":28,"value":2229},") ",{"type":23,"tag":154,"props":2231,"children":2232},{"style":240},[2233],{"type":28,"value":2234},"withBytes:NULL",{"type":23,"tag":154,"props":2236,"children":2237},{"style":173},[2238],{"type":28,"value":369},{"type":23,"tag":154,"props":2240,"children":2241},{"class":156,"line":689},[2242,2246,2251,2255,2259,2263,2267,2271,2275],{"type":23,"tag":154,"props":2243,"children":2244},{"style":161},[2245],{"type":28,"value":350},{"type":23,"tag":154,"props":2247,"children":2248},{"style":173},[2249],{"type":28,"value":2250}," [mutableData ",{"type":23,"tag":154,"props":2252,"children":2253},{"style":240},[2254],{"type":28,"value":985},{"type":23,"tag":154,"props":2256,"children":2257},{"style":173},[2258],{"type":28,"value":750},{"type":23,"tag":154,"props":2260,"children":2261},{"style":240},[2262],{"type":28,"value":611},{"type":23,"tag":154,"props":2264,"children":2265},{"style":240},[2266],{"type":28,"value":616},{"type":23,"tag":154,"props":2268,"children":2269},{"style":173},[2270],{"type":28,"value":1458},{"type":23,"tag":154,"props":2272,"children":2273},{"style":240},[2274],{"type":28,"value":1923},{"type":23,"tag":154,"props":2276,"children":2277},{"style":173},[2278],{"type":28,"value":1928},{"type":23,"tag":154,"props":2280,"children":2281},{"class":156,"line":697},[2282],{"type":23,"tag":154,"props":2283,"children":2284},{"style":173},[2285],{"type":28,"value":377},{"type":23,"tag":24,"props":2287,"children":2288},{},[2289],{"type":28,"value":2290},"Now, every time an attribute value is saved, its encrypted version includes an extra stage of randomization that prevents comparisons between different attributes encrypted with the same key.",{"type":23,"tag":24,"props":2292,"children":2293},{},[2294],{"type":28,"value":2295},"Thus, with fairly minimal code that ensures resilient encryption, we have an easy way to store private information in Core Data attributes with as many different keys as necessary.",{"type":23,"tag":2297,"props":2298,"children":2299},"style",{},[2300],{"type":28,"value":2301},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":8,"searchDepth":193,"depth":193,"links":2303},[2304,2311],{"id":70,"depth":184,"text":73,"children":2305},[2306,2307,2308],{"id":138,"depth":193,"text":141},{"id":282,"depth":193,"text":285},{"id":1044,"depth":193,"text":141,"children":2309},[2310],{"id":1085,"depth":203,"text":285},{"id":1606,"depth":184,"text":1609,"children":2312},[2313],{"id":1758,"depth":203,"text":1761},"markdown","content:nharrison:2012-07:core-data.md","content","nharrison/2012-07/core-data.md","nharrison/2012-07/core-data","md",{"user":2321,"name":2322},"nharrison","Noah Harrison",1780330272899]