/
709.srt
3864 lines (2861 loc) · 87.6 KB
/
709.srt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:00:10.316 --> 00:00:13.436 A:middle
>> Welcome to Session
709: Protecting Secrets
00:00:13.436 --> 00:00:17.116 A:middle
with the Keychain If you
have ever used a keychain
00:00:17.116 --> 00:00:20.526 A:middle
or if you think you should,
this is your session; iOS, OS X,
00:00:20.526 --> 00:00:26.766 A:middle
we're quite agnostic here
Let's get started What will you
00:00:26.766 --> 00:00:27.316 A:middle
learn here?
00:00:28.496 --> 00:00:31.346 A:middle
Well, I'll tell you what
keychains are I'll tell you how
00:00:31.346 --> 00:00:35.566 A:middle
to use them There is
iOS specific information
00:00:35.566 --> 00:00:38.726 A:middle
and there is OS X specific
information I'll mark them very
00:00:38.726 --> 00:00:41.476 A:middle
specifically so you know when
to go off and check your tweets
00:00:42.476 --> 00:00:45.576 A:middle
And pointers to more stuff
00:00:45.626 --> 00:00:49.636 A:middle
because there's always
more stuff All right
00:00:49.636 --> 00:00:51.166 A:middle
So why do we have a keychain?
00:00:51.936 --> 00:00:53.356 A:middle
We've actually had one
00:00:53.356 --> 00:00:57.046 A:middle
for a very long time There was
a keychain API and keychains
00:00:57.046 --> 00:01:02.736 A:middle
in Mac OS 9; so long time
There's a lot of small secrets
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:00:57.046 --> 00:01:02.736 A:middle
in Mac OS 9; so long time
There's a lot of small secrets
00:01:03.006 --> 00:01:04.866 A:middle
that your programs
need to handle --
00:01:05.046 --> 00:01:08.396 A:middle
passwords, account
numbers maybe, PINs --
00:01:09.976 --> 00:01:15.786 A:middle
you want to store them securely,
but you don't want to do
00:01:15.786 --> 00:01:19.256 A:middle
that cryptographic thing
because it sounds dangerous
00:01:19.256 --> 00:01:25.436 A:middle
and it's hard And you really
want to be as particular
00:01:25.436 --> 00:01:28.656 A:middle
as you can about who gets
those little secrets,
00:01:29.036 --> 00:01:32.786 A:middle
not just in terms of which
user, but also which programs
00:01:33.476 --> 00:01:36.206 A:middle
because we all know that not
all programs are is meticulous
00:01:36.206 --> 00:01:42.036 A:middle
with the user's secrets as yours
And you want some assurance
00:01:42.036 --> 00:01:46.486 A:middle
that if the user loses
their laptop or their iPhone
00:01:46.486 --> 00:01:48.306 A:middle
and somebody walks away with it,
00:01:48.306 --> 00:01:52.816 A:middle
those secrets actually
stay secrets That's called
00:01:52.816 --> 00:01:57.846 A:middle
"off-line attack" in
security lingo The control
00:01:57.846 --> 00:01:59.556 A:middle
over these secrets
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:02:00.406 --> 00:02:03.756 A:middle
in the keychain universe is
always the users This is kind
00:02:03.756 --> 00:02:07.216 A:middle
of important point
to get out of the way
00:02:07.216 --> 00:02:10.506 A:middle
up front These are the user's
secrets These are not your
00:02:10.506 --> 00:02:15.076 A:middle
secrets A keychain doesn't give
you a way of hiding something
00:02:15.246 --> 00:02:20.306 A:middle
from the user of the system
It's just a way for you
00:02:20.306 --> 00:02:23.976 A:middle
to protect the user's secrets
better and more easily And,
00:02:23.976 --> 00:02:26.686 A:middle
of course, we all know,
less code is better
00:02:27.076 --> 00:02:32.306 A:middle
So keychain APIs try to be a
high level API Fewer calls,
00:02:32.676 --> 00:02:35.076 A:middle
fewer parameters for the most
part It may not always seem
00:02:35.076 --> 00:02:36.206 A:middle
that way, but believe me,
00:02:36.206 --> 00:02:40.656 A:middle
the low-level solutions look
a lot worse than this Okay
00:02:40.656 --> 00:02:41.956 A:middle
So what is a keychain?
00:02:42.346 --> 00:02:44.986 A:middle
It's a database I
mean, in its heart,
00:02:45.126 --> 00:02:48.546 A:middle
it's a database It's got rows
00:02:48.546 --> 00:02:50.586 A:middle
which in keychain lingo
are called "items";
00:02:51.176 --> 00:02:52.336 A:middle
and the items have values,
00:02:52.406 --> 00:02:53.636 A:middle
that's where you
put the secrets;
00:02:53.636 --> 00:02:57.346 A:middle
and they have attributes which
is things that you find them by
00:02:57.346 --> 00:03:04.256 A:middle
or that you stick on the side
We call those "metadata."
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:02:57.346 --> 00:03:04.256 A:middle
or that you stick on the side
We call those "metadata."
00:03:04.256 --> 00:03:09.426 A:middle
And keychains are optimized
for storing small secrets
00:03:09.616 --> 00:03:12.476 A:middle
and finding them quickly
That's what they do
00:03:12.476 --> 00:03:13.596 A:middle
for a living You know,
00:03:13.596 --> 00:03:17.726 A:middle
the prototypical example is a
user's password to a website
00:03:17.856 --> 00:03:21.966 A:middle
or some web service or
something else; little secrets,
00:03:22.036 --> 00:03:26.716 A:middle
little individual secrets that
you use one at a time Now,
00:03:26.966 --> 00:03:29.116 A:middle
there is nothing in
the APIs that keeps you
00:03:29.116 --> 00:03:34.276 A:middle
from storing 150,000 secrets in
a keychain, and there's nothing
00:03:34.276 --> 00:03:35.326 A:middle
in the APIs that keeps you
00:03:35.326 --> 00:03:38.366 A:middle
from storing a 50 megabytes
large secret in the keychain
00:03:38.956 --> 00:03:42.076 A:middle
But don't do that because that's
not what the APIs are written
00:03:42.136 --> 00:03:45.676 A:middle
for You can do it, but it will
hurt It will definitely hurt
00:03:45.676 --> 00:03:48.436 A:middle
your program, and it may
hurt the system depending
00:03:48.436 --> 00:03:50.826 A:middle
on the circumstances
So remember,
00:03:50.826 --> 00:03:54.226 A:middle
this is for small secrets
Don't sweat it, you know;
00:03:54.226 --> 00:03:56.316 A:middle
couple hundred bytes is fine,
00:03:57.236 --> 00:04:01.586 A:middle
kilobytes probably fine
Thousands of secrets is fine
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:03:57.236 --> 00:04:01.586 A:middle
kilobytes probably fine
Thousands of secrets is fine
00:04:01.586 --> 00:04:04.696 A:middle
as long as you're not trying
to iterate through all of them
00:04:04.696 --> 00:04:06.026 A:middle
and pick them up one at a time
00:04:06.026 --> 00:04:08.516 A:middle
in your program while the
user waits So that's kind
00:04:08.516 --> 00:04:11.606 A:middle
of the environment they we're
here for You can stretch this,
00:04:11.926 --> 00:04:17.596 A:middle
just don't overstretch it
Yeah, and this is the point
00:04:17.596 --> 00:04:19.656 A:middle
where somebody always raises
their finger and says,
00:04:19.656 --> 00:04:24.066 A:middle
"I just write it to a file," you
know "I'll encrypt it myself,"
00:04:24.066 --> 00:04:26.176 A:middle
or "Why do I bother anyway?
00:04:26.176 --> 00:04:28.656 A:middle
I'll use ROT-13," you
know "Nobody's going
00:04:28.656 --> 00:04:31.946 A:middle
to find the data Why should
I call these weird APIs
00:04:31.946 --> 00:04:33.146 A:middle
with their weird
security things?"
00:04:35.046 --> 00:04:41.026 A:middle
Well, the keychain APIs give
you canned access control
00:04:41.026 --> 00:04:47.066 A:middle
Essentially, a predefined way
of determining what programs,
00:04:47.726 --> 00:04:50.366 A:middle
and to a certain extent,
what users get at the secret,
00:04:51.836 --> 00:04:56.216 A:middle
and they give you a way of
controlling how your program
00:04:56.216 --> 00:04:59.186 A:middle
and other programs can share
access to these secrets
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:05:00.626 --> 00:05:04.256 A:middle
If you write your secrets
to a file, then anybody
00:05:04.256 --> 00:05:06.456 A:middle
who gets a hold of the
file has the secret I mean,
00:05:06.456 --> 00:05:07.476 A:middle
they may not know where to look
00:05:07.476 --> 00:05:08.756 A:middle
but eventually they'll
figure it out,
00:05:08.756 --> 00:05:14.816 A:middle
and that's not good Plain
files, there is many,
00:05:14.816 --> 00:05:18.046 A:middle
many ways of scanning
for files in the system
00:05:18.276 --> 00:05:22.666 A:middle
And I don't just mean on OS X
There's ways of finding files
00:05:22.666 --> 00:05:28.646 A:middle
in iOS by Jailbreak or
other ways And besides,
00:05:28.646 --> 00:05:31.016 A:middle
when you start manipulating
this data yourself --
00:05:31.406 --> 00:05:33.766 A:middle
you copy it around, you write it
to a file, you fetch it back -
00:05:34.306 --> 00:05:36.236 A:middle
every time you make a
copy, there's another place
00:05:36.236 --> 00:05:41.636 A:middle
where the secret sits, and once
you lose control of a secret,
00:05:41.716 --> 00:05:44.566 A:middle
once it goes to places where
you didn't realize it was going,
00:05:44.566 --> 00:05:45.766 A:middle
there's no way of
getting it back
00:05:46.706 --> 00:05:51.196 A:middle
because you just wrote
it there Keychain is
00:05:51.336 --> 00:05:54.466 A:middle
about doing the cryptography
right without you having
00:05:54.466 --> 00:05:59.386 A:middle
to think about it And believe me
This is hard It really is very
00:05:59.386 --> 00:06:03.486 A:middle
hard And it's not typically
what you want to spend your time
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:05:59.386 --> 00:06:03.486 A:middle
hard And it's not typically
what you want to spend your time
00:06:03.486 --> 00:06:05.606 A:middle
on So that's why you want
00:06:05.606 --> 00:06:09.396 A:middle
to bother using the
keychain The less code,
00:06:09.396 --> 00:06:15.676 A:middle
the better So let's start
with the minimum kind
00:06:15.706 --> 00:06:18.646 A:middle
of code you can get away with
if your needs are simple --
00:06:18.916 --> 00:06:19.916 A:middle
you want to store a password,
00:06:19.916 --> 00:06:23.796 A:middle
you want to store a PIN You
can create a keychain item,
00:06:23.796 --> 00:06:26.446 A:middle
which is an entry in this
database that is the keychain,
00:06:26.446 --> 00:06:30.856 A:middle
with a single API call it's
called SecItemAdd It's a core
00:06:30.856 --> 00:06:34.106 A:middle
foundation level API, so
you pass it a CFDictionary
00:06:34.596 --> 00:06:37.856 A:middle
but we're all rather happier
with writing Objective-C code
00:06:37.916 --> 00:06:42.156 A:middle
so I wrote you the sample
code in Objective-C Basically,
00:06:42.156 --> 00:06:44.896 A:middle
what you do is, you make up a
dictionary, you stick in all
00:06:44.896 --> 00:06:47.716 A:middle
of the attributes that
you want the item to have,
00:06:48.056 --> 00:06:49.826 A:middle
you stick in the
value, you say go,
00:06:50.506 --> 00:06:54.346 A:middle
and it goes It returns an
OS status, and you always,
00:06:54.346 --> 00:06:55.806 A:middle
always check the OS status
00:06:55.806 --> 00:06:59.426 A:middle
of course You would never even
think of ignoring an error code
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:07:00.166 --> 00:07:06.846 A:middle
And that's it If the call
returns no error, zero,
00:07:07.036 --> 00:07:08.706 A:middle
then it worked You now
have a keychain item,
00:07:10.056 --> 00:07:11.846 A:middle
and you don't have to
worry about protecting it
00:07:11.846 --> 00:07:14.666 A:middle
because that's what
the API's for Okay
00:07:14.666 --> 00:07:15.826 A:middle
So how do you get it back?
00:07:16.106 --> 00:07:22.476 A:middle
Oh, one note Just like any
good database, it has a notion
00:07:22.836 --> 00:07:26.686 A:middle
of uniquely identifying items
In the case of these kinds
00:07:26.686 --> 00:07:29.346 A:middle
of items, that's the
service attribute
00:07:29.546 --> 00:07:31.996 A:middle
and the account attribute
And if you're trying
00:07:31.996 --> 00:07:35.446 A:middle
to create another item with the
same service and account values,
00:07:35.476 --> 00:07:39.296 A:middle
it will not work because
these are unique So one
00:07:39.296 --> 00:07:42.266 A:middle
of the errors you can get
back from SecItemAdd is,
00:07:42.396 --> 00:07:44.036 A:middle
this item already
exists so I'm not going
00:07:44.036 --> 00:07:49.116 A:middle
to make you another one So
keep that in mind Uniquing Okay
00:07:49.186 --> 00:07:53.266 A:middle
So this is how you get it
back SecItemCopyMatching,
00:07:53.926 --> 00:07:56.926 A:middle
which is literally what this
does Let me give you a bag
00:07:56.926 --> 00:07:59.986 A:middle
of attributes and I'll
match that against items
00:07:59.986 --> 00:08:03.416 A:middle
in the keychain and I'll give
you back the matching value
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:07:59.986 --> 00:08:03.416 A:middle
in the keychain and I'll give
you back the matching value
00:08:04.426 --> 00:08:08.756 A:middle
So this is the same
dictionary that you passed in,
00:08:09.526 --> 00:08:11.126 A:middle
with the same attributes,
00:08:11.666 --> 00:08:16.146 A:middle
service attribute an account
attribute You typically pass
00:08:16.146 --> 00:08:17.566 A:middle
in "return data", that is,
00:08:17.566 --> 00:08:21.626 A:middle
give me the value You can also
get back references to items
00:08:21.626 --> 00:08:24.326 A:middle
that let you manipulate the
items themselves And, again,
00:08:24.326 --> 00:08:25.546 A:middle
you check the error code,
00:08:25.546 --> 00:08:29.716 A:middle
it gives you back the value
These values, by the way,
00:08:29.716 --> 00:08:33.476 A:middle
are datas They're not strings Of
course, you know, secrets come
00:08:33.476 --> 00:08:36.785 A:middle
in many different shapes and
forms so keep that one in mind
00:08:38.905 --> 00:08:42.356 A:middle
And that's basically the
tools you have to work
00:08:42.356 --> 00:08:45.456 A:middle
with You can create an item
You can get the value back,
00:08:45.456 --> 00:08:48.646 A:middle
you know Sometimes
it's convenient
00:08:48.646 --> 00:08:51.086 A:middle
to do the other two things
that you typically do
00:08:51.086 --> 00:08:55.446 A:middle
with databases You can change
an existing item That's done
00:08:55.446 --> 00:08:59.176 A:middle
with SecItemUpdate This one
actually takes two dictionaries
00:08:59.236 --> 00:09:02.226 A:middle
because it's sort of a
combination of a lookup
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:08:59.236 --> 00:09:02.226 A:middle
because it's sort of a
combination of a lookup
00:09:02.226 --> 00:09:06.076 A:middle
and a creation; so it takes
one dictionary that you use
00:09:06.076 --> 00:09:09.176 A:middle
to find the item you want to
update, and another dictionary
00:09:09.176 --> 00:09:10.136 A:middle
with all of the stuff you want
00:09:10.136 --> 00:09:12.556 A:middle
to change It's really
quite straightforward
00:09:13.476 --> 00:09:15.906 A:middle
And we have a call for
deleting, which, again,
00:09:15.906 --> 00:09:18.876 A:middle
you pass a dictionary saying
which item you want to delete
00:09:18.876 --> 00:09:23.746 A:middle
and off it goes and deletes it
Always check your error codes
00:09:23.826 --> 00:09:28.096 A:middle
And there you have it: Keychain
APIs That's all you need to know
00:09:28.646 --> 00:09:32.706 A:middle
When you want to change an
item, a lot of people fall
00:09:32.706 --> 00:09:34.896 A:middle
into that one, really
change the item,
00:09:34.896 --> 00:09:39.606 A:middle
use SecItemUpdate It's sometimes
tempting to go, "Yeah, well,
00:09:39.606 --> 00:09:43.806 A:middle
I'll just delete the old item
I'll make a new one Who's going
00:09:44.826 --> 00:09:45.666 A:middle
to notice?"
00:09:45.796 --> 00:09:50.376 A:middle
Programs will notice because
there are attributes to items
00:09:50.656 --> 00:09:52.456 A:middle
that you may not actually
know about There are --
00:09:52.456 --> 00:09:54.586 A:middle
there may be attributes
to items that don't exist
00:09:54.586 --> 00:09:56.396 A:middle
yet because we'll invent
them in the next version
00:09:56.396 --> 00:09:59.756 A:middle
of the operating system
If you delete an item,
00:09:59.826 --> 00:10:04.066 A:middle
you're throwing everything about
it away You forget about it,
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:09:59.826 --> 00:10:04.066 A:middle
you're throwing everything about
it away You forget about it,
00:10:04.066 --> 00:10:06.616 A:middle
and then you make a new one
and it gets default values
00:10:06.616 --> 00:10:07.806 A:middle
for stuff you don't specify,
00:10:07.996 --> 00:10:10.366 A:middle
and this may not actually
be the same values
00:10:10.366 --> 00:10:13.356 A:middle
that the old item had; so
don't do that If you need
00:10:13.356 --> 00:10:17.246 A:middle
to change an existing keychain
item, use SecItemUpdate
00:10:17.886 --> 00:10:23.126 A:middle
because that way, you
keep the stuff And --
00:10:23.626 --> 00:10:26.126 A:middle
well, if you're in a situation
00:10:26.126 --> 00:10:29.346 A:middle
where you have a
particular place in your UI
00:10:29.946 --> 00:10:34.116 A:middle
where the user gives you
the secret for safekeeping,
00:10:35.216 --> 00:10:38.996 A:middle
then you call SecItemAdd
right there And then
00:10:38.996 --> 00:10:40.406 A:middle
if you have another
place in your code
00:10:40.486 --> 00:10:44.106 A:middle
where you know now you need it,
you call SecItemCopyMatching,
00:10:44.366 --> 00:10:47.986 A:middle
and these calls are
all you need But a lot
00:10:47.986 --> 00:10:52.186 A:middle
of times that's not really
what you want to do A lot
00:10:52.186 --> 00:10:54.156 A:middle
of times you start
to write your program
00:10:54.226 --> 00:10:56.946 A:middle
and it goes something
like, oh, I need to connect
00:10:56.946 --> 00:10:59.446 A:middle
to that website Oh, wait
He says I need a password,
00:10:59.446 --> 00:11:01.326 A:middle
so let's go ask the
user about the password,
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:10:59.446 --> 00:11:01.326 A:middle
so let's go ask the
user about the password,
00:11:01.726 --> 00:11:05.016 A:middle
pop up a dialog or, you
know, something like that,
00:11:05.206 --> 00:11:07.686 A:middle
and the user types
in the password,
00:11:07.686 --> 00:11:09.546 A:middle
you send it to the
website, and that's great
00:11:09.546 --> 00:11:12.316 A:middle
until it happens again and
you ask the user again So, no,
00:11:12.316 --> 00:11:15.076 A:middle
wait I heard this is keychain,
so let's use that keychain
00:11:15.076 --> 00:11:18.586 A:middle
to remember the thing that the
user gave me I call this the
00:11:18.586 --> 00:11:23.096 A:middle
"memory work flow" because it's
really not a store and retrieve
00:11:23.156 --> 00:11:25.236 A:middle
from the user's perspective
The user just want
00:11:25.236 --> 00:11:27.446 A:middle
to remember something
he's already told you once
00:11:28.696 --> 00:11:32.016 A:middle
And this happens often enough
that I wrote up a little bit
00:11:32.016 --> 00:11:36.816 A:middle
of pseudo code just to get you
started with it What you do
00:11:36.816 --> 00:11:39.136 A:middle
in a situation where, oh,
suddenly I need a password,
00:11:39.616 --> 00:11:41.746 A:middle
is the first thing you do is
you look it up in the keychain
00:11:41.936 --> 00:11:45.556 A:middle
in case it's already
there And if that worked,
00:11:45.616 --> 00:11:49.686 A:middle
if the keychain retrieval
succeeds, you just take this
00:11:49.686 --> 00:11:52.066 A:middle
and you use it and you don't
bother the user That's,
00:11:52.066 --> 00:11:56.066 A:middle
after all, the whole point
of this If you don't find it
00:11:56.066 --> 00:11:58.366 A:middle
in the keychain, then go
off and ask the user --
00:11:59.956 --> 00:12:01.896 A:middle
this may be the first
time or, you know,
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:11:59.956 --> 00:12:01.896 A:middle
this may be the first
time or, you know,
00:12:02.076 --> 00:12:04.246 A:middle
something may have
happened to the keychain --
00:12:04.366 --> 00:12:07.876 A:middle
and the user gives you the
password and you try it out,
00:12:07.876 --> 00:12:09.956 A:middle
and if it works, then you
stick it in the keychain
00:12:09.956 --> 00:12:13.726 A:middle
with SecItemAdd so that the
next time when you're running
00:12:13.726 --> 00:12:16.346 A:middle
through the same code flow,
you're hitting the copy matching
00:12:16.346 --> 00:12:19.586 A:middle
at the top and you don't
ask the user again This is
00:12:19.586 --> 00:12:20.456 A:middle
about as straightforward
00:12:20.456 --> 00:12:24.276 A:middle
as it can go The password
you retrieved or the password
00:12:24.276 --> 00:12:27.586 A:middle
that the user gave you may not
actually work The user may have
00:12:27.616 --> 00:12:30.166 A:middle
mistyped it or it may
have been changed;
00:12:30.796 --> 00:12:34.656 A:middle
so you do need code for,
well, that didn't work
00:12:35.586 --> 00:12:37.956 A:middle
And give a little bit of
thought to what you do
00:12:37.956 --> 00:12:44.406 A:middle
when it didn't work Try it first
before you store in the keychain
00:12:45.266 --> 00:12:46.396 A:middle
If it didn't work --
00:12:46.396 --> 00:12:49.536 A:middle
the keychain item you've
retrieved didn't work
00:12:49.536 --> 00:12:50.826 A:middle
and you ask the user
for a new one,
00:12:51.026 --> 00:12:54.936 A:middle
try that one before you go off
and replace it in the keychain
00:12:55.056 --> 00:12:58.576 A:middle
But it's basically your workflow
I didn't put a loop in here
00:12:58.576 --> 00:13:01.386 A:middle
If you want to keep asking
the user three times,
WEBVTT
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
00:12:58.576 --> 00:13:01.386 A:middle
If you want to keep asking
the user three times,
00:13:01.386 --> 00:13:04.476 A:middle
as many of you want, you
know, just add the code,
00:13:04.676 --> 00:13:08.286 A:middle
the obvious code, but that's
basically the idea This is how
00:13:08.286 --> 00:13:11.956 A:middle
to just remember stuff for the
user The only thing the user
00:13:11.956 --> 00:13:15.666 A:middle
notices is that you don't
keep asking the same question,
00:13:15.876 --> 00:13:21.276 A:middle
which is kind of the Apple
thing Couple things to think
00:13:21.276 --> 00:13:24.296 A:middle
about when you build
this workflow: As I said,
00:13:25.136 --> 00:13:27.446 A:middle
don't store a password until
you have some assurance
00:13:27.446 --> 00:13:31.256 A:middle
that it works; It's kind
of silly to store something
00:13:31.256 --> 00:13:35.976 A:middle
that turns out not to be the
right secret If you can at all,
00:13:35.976 --> 00:13:40.066 A:middle
when you try out this password,
this secret, this PIN, whatever,
00:13:41.296 --> 00:13:45.026 A:middle
try to distinguish between
this is the wrong password