YouTube2Text

Certificate Pinning - The MOST Important Security Measure for Network Traffic In Your App — Transcript

by Philipp Lackner · 4,042 words · 587 segments · language en · Watch on YouTube

Full transcript

  1. 0:00In this video, we're going to take a
  2. 0:01look at certificate pinning on Android,
  3. 0:03which is a very important concept to
  4. 0:05know about when you're working on
  5. 0:06security critical apps that involve some
  6. 0:08form of network traffic like a banking
  7. 0:10app or something like health related
  8. 0:13apps with users health data that has
  9. 0:15been somehow exchanged over the network.
  10. 0:17But first of all, let's understand what
  11. 0:18a certificate is really for in the first
  12. 0:20place. You've probably heard this before
  13. 0:22that when wanting to communicate with a
  14. 0:25server via HTTPS, that is on the one
  15. 0:27hand encrypted by default. That is what
  16. 0:29the S stands for. So, hypertext transfer
  17. 0:32protocol secure and that in order to
  18. 0:34enable HTTPS on your server, you need a
  19. 0:38signed certificate. How do you actually
  20. 0:40know there is not any sort of attacker
  21. 0:42in the middle between your app and your
  22. 0:44server? Because if the attacker actually
  23. 0:46kind of owns this communication channel,
  24. 0:48they could of course kind of also fake a
  25. 0:50response even if that response is
  26. 0:51encrypted, feed that encrypted response
  27. 0:54back to your app, which your app wrongly
  28. 0:57interprets as the real response from the
  29. 0:58server. And in order to know that a
  30. 1:01server is trustworthy, it has to have a
  31. 1:04certificate that is signed by a
  32. 1:05so-called CA. So a certificate
  33. 1:08authority. So there are in the end a
  34. 1:10bunch of such certificate authorities
  35. 1:12that the general public considers
  36. 1:14trustworthy which is in the end
  37. 1:16responsible of signing such
  38. 1:18certificates. So examples for such
  39. 1:20certificate authorities are Google or
  40. 1:22Amazon. So where you would say if Google
  41. 1:24or Amazon actually signs a certificate
  42. 1:26and we can actually see that it was
  43. 1:27signed by one of these then that should
  44. 1:29be trustworthy. So what now happens when
  45. 1:31your Android app is making a normal
  46. 1:32HTTPS request to a server that owns a
  47. 1:36certificate and exposes a certificate
  48. 1:38that was signed by such a certificate
  49. 1:40authority. What happens is when your app
  50. 1:43then gets the response, it has a
  51. 1:44predefined OS level list of these
  52. 1:48certificate authorities. So there are a
  53. 1:50bit over a hundred of such authorities
  54. 1:51that are predefined and baked into the
  55. 1:53OS. Technically, you can also define
  56. 1:56your own of such authorities and allow
  57. 1:58these. But there's definitely a
  58. 2:00predefined list that when your app then
  59. 2:03receives the response, we'll simply go
  60. 2:04over and see, okay, is the signature of
  61. 2:07this response that we got from this
  62. 2:09network call actually matching any of
  63. 2:11these certificate authorities that have
  64. 2:13been predefined. If it matches, then
  65. 2:15your app will simply accept the traffic
  66. 2:17because a trustworthy authority has
  67. 2:20signed the certificate. So this means
  68. 2:22it's not that easy for an attacker to
  69. 2:23actually just fake being Amazon or fake
  70. 2:26being Google because they don't have
  71. 2:27that signature these companies have. But
  72. 2:30if it doesn't match and the attacker
  73. 2:32maybe just try to generate their own
  74. 2:34certificate which will then however have
  75. 2:36a different signature then that
  76. 2:38signature won't match against any of
  77. 2:40these predefined certificate authorities
  78. 2:42on your Android device and that response
  79. 2:45will in that case be declined. so much
  80. 2:47about the theory of how these
  81. 2:49certificates work, but we're not yet at
  82. 2:51certificate pinning because in the end,
  83. 2:53the weakest link here breaks the chain.
  84. 2:55This connection that you've seen here on
  85. 2:57the previous slide is in in the end only
  86. 2:59as trustworthy as the certificate
  87. 3:01authority is. Or in other words, it's
  88. 3:04only as trustworthy as the kind of
  89. 3:06weakest link. So the weakest certificate
  90. 3:08authority here in this whole list of
  91. 3:10predefined authorities is what can now
  92. 3:12happen is that such a certificate
  93. 3:14authority is maybe compromised in some
  94. 3:16way. It could happen that a malicious
  95. 3:19certificate is actually issued. So an
  96. 3:21attacker gets some chance to actually
  97. 3:22generate a real certificate for your
  98. 3:25domain by I don't know getting access to
  99. 3:27your server or so. Or it could simply
  100. 3:29happen that a malicious certificate
  101. 3:31authority is simply sitting on your
  102. 3:32device. As I mentioned, this list can be
  103. 3:34extended and if there's some kind of a
  104. 3:37malicious software on the Android device
  105. 3:39that simply extends this list of
  106. 3:41predefined certificate authorities and
  107. 3:43it now says, okay, we have all these
  108. 3:46trustworthy certificate authorities,
  109. 3:48Amazon, Google, etc. But now let's also
  110. 3:50have this additional one here that is
  111. 3:53technically from me. So the attacker
  112. 3:55does as if they are a certificate
  113. 3:57authority by just adding this to this
  114. 3:58predefined list. This would also be a
  115. 4:01valid scenario here. So in these cases,
  116. 4:03that's actually a problem because in any
  117. 4:05of these three cases, it could
  118. 4:06technically happen that with this
  119. 4:08so-called man-in-the-middle attack that
  120. 4:09an attacker is kind of intercepting your
  121. 4:12network traffic and I don't know is
  122. 4:14maybe listening to your login data, you
  123. 4:17send that and while they can't instantly
  124. 4:19read what you send because it's
  125. 4:21encrypted, they could decide about the
  126. 4:23response. So they could do something
  127. 4:24like just send you a generic error
  128. 4:28message here that they say, "Okay, that
  129. 4:30password wasn't valid." and they kind of
  130. 4:31redirect you to a different website that
  131. 4:33looks identical or so. So you just
  132. 4:35re-enter the password and then with the
  133. 4:37next request they have it. Something
  134. 4:39like that is definitely then possible if
  135. 4:41an attacker then kind of yeah is in the
  136. 4:43same network for example in the public
  137. 4:45Wi-Fi. And this of course something we
  138. 4:47want to prevent with security critical
  139. 4:49apps and for exactly that certificate
  140. 4:52pinning exists. Certificate pinning in
  141. 4:54the end really means that in our Android
  142. 4:57app we embed a list of hashes of servers
  143. 5:02public keys that we explicitly trust. So
  144. 5:05in the end of course all these
  145. 5:07certificates are lying on some kind of
  146. 5:09servers that our app connects to that
  147. 5:10our app needs to make network calls to
  148. 5:12and a certificate consists of multiple
  149. 5:14different parts but part of that are for
  150. 5:16example a public and a private key. The
  151. 5:17private key is what the server uses,
  152. 5:19what is definitely a secret, what's used
  153. 5:21to encrypt the thre the traffic back.
  154. 5:23And the public key here is really just
  155. 5:24used to verify a signature. So on the
  156. 5:27one hand, we have this list of such
  157. 5:29hashed public keys sitting inside of our
  158. 5:32Android app that is really embedded into
  159. 5:33our APK. And on the other hand, there is
  160. 5:36this one public key here that is sitting
  161. 5:39on the server. And it's actually one
  162. 5:41such public key per domain or subdomain.
  163. 5:44And this public key is simply part of
  164. 5:46this overall certificate which however
  165. 5:47comes with more such entries. And when
  166. 5:50our app now gets a response from a
  167. 5:52certain server. What it can now do of
  168. 5:54course is it can match this public key
  169. 5:56from the server against the undefined
  170. 5:59list of public keys. So we could say hey
  171. 6:03here this is a list of public keys of
  172. 6:06servers or of certificates that we
  173. 6:08actually trust and only if this public
  174. 6:11key that we get back from the
  175. 6:12certificate from the server matches any
  176. 6:15of these then we trust that response and
  177. 6:17this is then what we call it matches a
  178. 6:19pin. So we really pin these public keys.
  179. 6:22And the problem this really solves is
  180. 6:23even if an attacker gains access and
  181. 6:25compromises the certificate authority.
  182. 6:27So is in the position to actually create
  183. 6:30new trustworthy certificates for your
  184. 6:33domain. Those will still be other
  185. 6:35certificates that won't be the exact
  186. 6:37same certificate as the one sitting on
  187. 6:39your server. And if you now say, okay, I
  188. 6:41know the one that is sitting on my
  189. 6:43server, you can actually kind of
  190. 6:44hardcode exactly that certificate in
  191. 6:47your Android app and you only trust that
  192. 6:49exact instance of a certificate that is
  193. 6:52sitting on your server. And that is
  194. 6:53typically working via the public key,
  195. 6:55not by hashing the entire certificate,
  196. 6:57that would be a big mistake because if
  197. 6:59you would hash the entire certificate,
  198. 7:01the certificate itself would change when
  199. 7:03it's being renewed. So that's something
  200. 7:06that is a very standard practice and
  201. 7:07it's happening typically every 90 days
  202. 7:09with these certificates that is that
  203. 7:10they are simply renewed and regenerated
  204. 7:13but that would then also break your app
  205. 7:17because your app is still installed on
  206. 7:19users devices but if the certificate is
  207. 7:21changed and the hash therefore has
  208. 7:23changed then your Android app will break
  209. 7:25because it doesn't match anymore after
  210. 7:27it has changed. However, what is
  211. 7:29definitely possible is to renew a
  212. 7:31certificate without actually touching
  213. 7:33the public and private key here. And
  214. 7:35this is a very important setting for you
  215. 7:36to make here because otherwise you can
  216. 7:38really lock out your users here. But if
  217. 7:41your server is actually configured in a
  218. 7:43way that this keeper won't change when
  219. 7:46the certificate renews, then this will
  220. 7:48obviously also survive renewals. On
  221. 7:50Android, there are two different ways to
  222. 7:51do that. On the one hand, via the
  223. 7:53manifest. That's something I will also
  224. 7:54really show you in a moment practically.
  225. 7:56So you really just define a so-called
  226. 7:58network security config or alternatively
  227. 8:01you can directly configure this in your
  228. 8:03network client of choice something like
  229. 8:05okay HTTP or KO here in this case you're
  230. 8:07really dynamically define these
  231. 8:09certificates in your code but the
  232. 8:11easiest approach is usually just
  233. 8:12defining the network security config
  234. 8:14when is this actually justified well not
  235. 8:17generally because as I mentioned um
  236. 8:19there is a real risk here if you're
  237. 8:20doing this wrong you can really lock out
  238. 8:23your users but for any apps that are
  239. 8:25really like uh security critical like
  240. 8:28banking app, fintech, password managers,
  241. 8:31apps dealing with health data or any
  242. 8:33super sensitive data that is also shared
  243. 8:35over the network. Here it really makes
  244. 8:37sense to think about certificate pinning
  245. 8:39and really implementing this correctly.
  246. 8:41Where it's usually not making sense is
  247. 8:43any typical like consumer apps for
  248. 8:46example a calorie tracker or some kind
  249. 8:48of game. So this is really something for
  250. 8:51apps where you say I really need the
  251. 8:53highest level of security and I can't
  252. 8:55tolerate anything below that. But if you
  253. 8:58have an app where there is no real
  254. 9:00strong external interest from someone
  255. 9:02from a positive attacker to get
  256. 9:04something from this app then you also
  257. 9:06don't need to think about certificate
  258. 9:07pinning and it's rather just overkill.
  259. 9:09So I'm now here in Android Studio and I
  260. 9:11want to now show you how that really
  261. 9:12works in practice by having a real app
  262. 9:15where we will now implement this. And
  263. 9:17this is really just a a little prepared
  264. 9:19app here that is making a network call
  265. 9:22each here for these two button clicks.
  266. 9:24On the one end, we're making a get
  267. 9:25request to PL coding to my website. And
  268. 9:27[clears throat] here we have a get
  269. 9:28request to Google. And right now, no
  270. 9:31certificate pinning is implemented at
  271. 9:32all. So that means if we click this
  272. 9:34button, it will in this case simply
  273. 9:36print the response. You can see making
  274. 9:38the request here. In my case, my website
  275. 9:40redirects you to the www variant. And
  276. 9:44then here after making the request over
  277. 9:47there, this is kind of the raw HTML that
  278. 9:50my my homepage responded with. So that
  279. 9:54call is definitely going through here as
  280. 9:55we can see in lockat. And if we make the
  281. 9:57request to Google, then we can also see
  282. 9:59yeah similar thing is happening here.
  283. 10:01And then here's the entire HTML from
  284. 10:03Google in this case. But now let's say
  285. 10:06we h have an app where this network
  286. 10:08traffic to PL coding must really be
  287. 10:11secure and we also maybe don't want to
  288. 10:13allow the network traffic to Google at
  289. 10:14all. So what we want to do is we want to
  290. 10:17go inside our
  291. 10:20resources package inside XML and this is
  292. 10:24the place where we need to define a
  293. 10:25network security config. So that's
  294. 10:27really nothing else than just a normal
  295. 10:29plain XML file. So XML resource file in
  296. 10:32this case we want to create this. We'll
  297. 10:34call it network security config
  298. 10:39and the root element here would be
  299. 10:41exactly that network but here with
  300. 10:43dashes network security config and then
  301. 10:47we can create this. The autocomplete is
  302. 10:49usually broken here but that doesn't
  303. 10:52mean that it won't work. And the first
  304. 10:53thing we want to do is want to define a
  305. 10:55base config. The base config in the end
  306. 10:57defines well the config for any domains
  307. 11:00that we don't explicitly define
  308. 11:02something for. So in this network
  309. 11:03security config we now have a fine
  310. 11:05grained configuration after all where we
  311. 11:08can define per domain technically per
  312. 11:10subdomain
  313. 11:12whether we want to pin some certificates
  314. 11:13there and if so which ones those are or
  315. 11:16rather which public keys of which
  316. 11:18certificates those are and what I will
  317. 11:20do is I will now add trust anchors here
  318. 11:25and intentionally cut this off. So what
  319. 11:28this will in the end do by just having
  320. 11:29this empty trust anchors block this by
  321. 11:32default won't trust anything. So we kind
  322. 11:36of deny all network traffic if we would
  323. 11:38really just leave it like that. We can
  324. 11:39technically also try this. In order to
  325. 11:42do so we need to link this network
  326. 11:43security config in our Android manifest
  327. 11:46simply here in the application tag. We
  328. 11:48would want to have an Android oops not
  329. 11:50like that but Android network security
  330. 11:53config. And here we want to then link
  331. 11:55this from our XML files like this. If we
  332. 11:59now run this once more and we now also
  333. 12:02take a look here in lockcat and we now
  334. 12:05make a request to PL coding then you
  335. 12:08will see we instantly get a cert path of
  336. 12:10validator exception because the trust
  337. 12:13anchor for certification path was not
  338. 12:15found. So this in the end fails because
  339. 12:19with this config we technically disallow
  340. 12:22any sort of responses from any sort of
  341. 12:24server. Now that's of course not what we
  342. 12:26want. We want to pin our own server
  343. 12:29certificate here. So we allow the
  344. 12:32traffic we allow the responses in this
  345. 12:34case from PL coding but only from the
  346. 12:37certificate or from the public key of
  347. 12:40the certificate that the real PL coding
  348. 12:43site owns or is signed with after all.
  349. 12:47And the way this works is below this
  350. 12:48base config we want to have a domain
  351. 12:51config. So here we can now kind of
  352. 12:52override domain specific um behavior or
  353. 12:55rules and we can define such rules just
  354. 12:58for technically for the entire domain
  355. 13:01but you could even define this just for
  356. 13:03a few certain security critical
  357. 13:05endpoints. So we can say we have this
  358. 13:08for a certain domain and let's say we
  359. 13:10also want to include subdomains in this
  360. 13:12case. So we set this to true and the
  361. 13:14domain in this case will simply be PL
  362. 13:16code income. Then here we can also
  363. 13:18define certain trust anchors and this
  364. 13:20could be a certificates block where we
  365. 13:23can give this a specific source and
  366. 13:25simply say system so that the the
  367. 13:27certificates from the certificate
  368. 13:29authorities simply come from the system
  369. 13:31just the OS level predefined certificate
  370. 13:34authorities and then where the magic now
  371. 13:36really starts to happen is when we
  372. 13:37define a so-called pin set so a set of
  373. 13:41pinned certificates after all or s
  374. 13:43pinned public keys it's not the entire
  375. 13:45certificate that gets pinned or just a
  376. 13:47public key. But still, we typically call
  377. 13:49this certificate pinning. So that is
  378. 13:51what I will also use for the rest of
  379. 13:52this video. And here we want to define
  380. 13:54an expiration. This expiration could
  381. 13:57technically be the expiration of the
  382. 13:58certificate, but usually not. If your
  383. 14:02server is configured correctly and the
  384. 14:04certificate renewal is configured
  385. 14:06correctly so that it won't actually
  386. 14:08replace the private key here when the
  387. 14:10certificate is renewed, then this
  388. 14:13expiration here technically does not
  389. 14:14matter. And this is how you should
  390. 14:16configure it. But I really want to
  391. 14:17highlight this is usually not the
  392. 14:19default um for how these certificates
  393. 14:22are renewed. Um if you use something
  394. 14:24like let's encrypt certificates, this is
  395. 14:26the most popular free variant for
  396. 14:27getting such a certificate then the
  397. 14:29default config for that is actually not
  398. 14:32leaving the keys unchanged but actually
  399. 14:33also rotating them. So if you use that
  400. 14:36you would need an additional terminal
  401. 14:37flag or um like config setting for let's
  402. 14:40encrypt in this case that would really
  403. 14:42make sure these keys are left unchanged.
  404. 14:44But this expiration attribute here is
  405. 14:47kind of um a backup in case something
  406. 14:50really goes wrong because it will in the
  407. 14:52end let us define a date that is
  408. 14:54sometime in the in the future like uh
  409. 14:572027 let's say the first of 2027
  410. 15:01and then in here we can define a bunch
  411. 15:03of pins so specifically pinned public
  412. 15:06keys but the this pin set will only be
  413. 15:09applied until that exact date. So this
  414. 15:12means even if something breaks server
  415. 15:13set it even if we accidentally rotate
  416. 15:16our public private key pier and
  417. 15:18therefore our pin set of these previous
  418. 15:20keys would break and would disallow any
  419. 15:22sort of traffic our app can make to this
  420. 15:24domain then from this date it will work
  421. 15:27again because this pin set is only
  422. 15:29applied until then and at this date it
  423. 15:31will expire because you must imagine
  424. 15:33this is quite problematic if you if this
  425. 15:34accidentally happens and you have your
  426. 15:36Android app installed to tous thousands
  427. 15:39of users devices that really hardcode
  428. 15:41these pins we will define in a moment.
  429. 15:43But if then the server side changes
  430. 15:46something about that that breaks
  431. 15:47something on the client. The only way
  432. 15:49for you to really fix this is to get a
  433. 15:51new update with a new set of pins for
  434. 15:54the new certificate for the new public
  435. 15:56key on their devices. But if you've
  436. 15:59worked with Google Play before, if
  437. 16:00you've published apps before, you know
  438. 16:02how long that can take. You have to
  439. 16:04submit your app for approval. And even
  440. 16:06if it's approved, it technically has to
  441. 16:07end up on your users's devices. It's not
  442. 16:09like a website where you simply push an
  443. 16:11update and everybody who visits it from
  444. 16:12this point on will see it. But really
  445. 16:15like this deploying the app not just to
  446. 16:17Google Play but to all your users this
  447. 16:19can take a long while and up to then
  448. 16:21your app will pretty much be unusable if
  449. 16:24you break this and that's why there is a
  450. 16:25real danger attached to certificate
  451. 16:27pinning. So this is kind of a yeah a
  452. 16:29fallback or something that you could
  453. 16:31define from this point on certificate
  454. 16:34pinning won't be applied anymore for
  455. 16:36this particular pin set and from this
  456. 16:38point on in that kind of catastrophic
  457. 16:40case your app would start working again
  458. 16:41but this also means that before this if
  459. 16:44you define such an expiration you would
  460. 16:46actually have to update your app with a
  461. 16:48later expiration time because otherwise
  462. 16:50even if you don't rotate the keys it
  463. 16:53could still happen that you reach this
  464. 16:55date and it will simply not be applied
  465. 16:56anymore even though these pins would
  466. 16:58still be valid. So you just have to
  467. 17:00regularly publish updates with later
  468. 17:03expiration dates in this case if you
  469. 17:05stick to that or otherwise the
  470. 17:06certificate pinning approach will
  471. 17:07completely lose its point. But in the
  472. 17:10end we want to define a pin here or
  473. 17:12possibly multiple pins and so you have
  474. 17:14to define one such pin per domain or
  475. 17:17subdomain. We want to define a digest
  476. 17:20because these pins or the public keys
  477. 17:22here are hashed in the end with
  478. 17:24typically sha
  479. 17:26256. And then here for this pin we
  480. 17:29really just pass the hashed variant of
  481. 17:31our servers public key. There are
  482. 17:33certain terminal commands that in the
  483. 17:35end give you that. I will just show you
  484. 17:37one of them here that I actually use and
  485. 17:39that is here via OpenSL that at least
  486. 17:41works on Mac OS. Define your domain.
  487. 17:44This is the port for HTTPS. define your
  488. 17:47domain again and then um yeah you you
  489. 17:49just look for certain attributes here
  490. 17:52from the certificate and then we want to
  491. 17:54get the base 64 encoded version of that
  492. 17:56because that is what Android Studio is
  493. 17:58looking for. If we do this then
  494. 18:00something went wrong here with copy
  495. 18:02pasting. But if I actually show you my
  496. 18:05terminal that I've opened here then you
  497. 18:07can see we actually get something like
  498. 18:09this and if it looks like something like
  499. 18:11this and also ends with this equal then
  500. 18:13that means that that is what we are
  501. 18:14looking for and this is something I I
  502. 18:16did now here for the www variant but we
  503. 18:20need it for both. So with that or just
  504. 18:23the plain domain so that's something we
  505. 18:25want to copy. want to paste that in here
  506. 18:28and we want to do the same thing um for
  507. 18:31the plain domain variant which I've also
  508. 18:33retrieved here via the same command just
  509. 18:36replacing the domain in this case and
  510. 18:38this here would be the two hashes that
  511. 18:40we need and that we in this case pin
  512. 18:42that means if we now rerun our app with
  513. 18:45this updated config. So again we have
  514. 18:48linked this here and we have two
  515. 18:50requests on the one hand to PL coding
  516. 18:52and one on the other one to Google. If
  517. 18:54we make the one to Google then after a
  518. 18:57little moment we will actually get our
  519. 19:00network exception again because the
  520. 19:02trust anchor for the certification path
  521. 19:04was not found. So with our config we
  522. 19:07kind of disallow responses from any sort
  523. 19:09of domain except for our own one where
  524. 19:12we pin those certificates. So if we now
  525. 19:14actually do the same for the PL coding
  526. 19:17domain then you can see that's actually
  527. 19:19going through and we actually get our
  528. 19:20HTML here. So this response was properly
  529. 19:23retrieved. But if someone would now go
  530. 19:25ahead and would technically compromise
  531. 19:28the certificate authority that has
  532. 19:30signed the certificate for plcoding.com,
  533. 19:32then they would have their own
  534. 19:33certificate that would technically be
  535. 19:35considered valid by most devices because
  536. 19:37they trust that certificate authority,
  537. 19:39but not by our app because we say for
  538. 19:42this domain, we only trust certificates
  539. 19:45that match exactly these kinds of
  540. 19:47fingerprints. And because a new
  541. 19:49certificate will have its own public
  542. 19:50key, that won't work. And that's the
  543. 19:53whole point of certificate pinning. Now,
  544. 19:55I really want to say here this base
  545. 19:56config thing is only something I did in
  546. 19:58order to showcase what I wanted to
  547. 20:00showcase that certain traffic is
  548. 20:01disallowed that other certain traffic is
  549. 20:03allowed. But this is something you
  550. 20:05usually don't want to have as a config
  551. 20:07generally that you just disallow any
  552. 20:08sort of traffic. So normally you just
  553. 20:10have something like the domain config.
  554. 20:12You just define those pin certificates
  555. 20:14for your domain or you want to actually
  556. 20:15pin something with. But other than that
  557. 20:17with this base config it can be very
  558. 20:19very dangerous because maybe third party
  559. 20:21SDK is making a network call to some
  560. 20:23kind of URL as well and this would also
  561. 20:25be blocked like that. But with this
  562. 20:26config you can technically define
  563. 20:28exactly what is allowed in your network
  564. 20:30um policy and whatn not. If these kinds
  565. 20:33of system design level topics are
  566. 20:34actually something you want to get
  567. 20:35deeper into and you really want to learn
  568. 20:37making the right technical decisions and
  569. 20:39really understanding tradeoffs,
  570. 20:41approaching large projects
  571. 20:42systematically, then this kind of
  572. 20:44thinking I can help you get in our
  573. 20:46senior app developer mentoring. Down
  574. 20:48below this video there is a link where
  575. 20:49you can apply where we can take a look
  576. 20:50how this could work. We're doing this
  577. 20:52for four years really helping Android
  578. 20:53developers around the globe become
  579. 20:55really really confident technically and
  580. 20:57just help them get to the next level in
  581. 20:59their career. Maybe that could be
  582. 21:00something for you. So, check the link in
  583. 21:02this video's description. And other than
  584. 21:03that, thanks for watching. I'll see you
  585. 21:05back in the next video. Have an amazing
  586. 21:06rest of your week. [music] Bye-bye.
  587. 21:18[music]

About this transcript

This page contains the full transcript of Certificate Pinning - The MOST Important Security Measure for Network Traffic In Your App by Philipp Lackner, generated from the public captions YouTube serves with the video. The transcript has 4,042 words across 587 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.