mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-11 18:24:43 +02:00
367 lines
17 KiB
HTML
367 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<!--
|
|
|
|
!!! WARNING !!!
|
|
|
|
This file was auto-generated from readme/blog/20200406-224254.md and any manual change
|
|
made to it will be overwritten. To make a change to this file please modify
|
|
the source Markdown file:
|
|
|
|
https://github.com/laurent22/joplin/blob/dev/readme/blog/20200406-224254.md
|
|
|
|
-->
|
|
|
|
<head>
|
|
<!-- Donate button A/B testing -->
|
|
<script async src="https://www.googleoptimize.com/optimize.js?id=OPT-PW3ZPK3"></script> <meta
|
|
charset="utf-8"
|
|
http-equiv="X-UA-Compatible"
|
|
content="IE=edge,chrome=1"
|
|
/>
|
|
<link rel="icon" href="/images/favicon.png" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<meta name="theme-color" content="#000000" />
|
|
<meta name="description" content="Joplin, the open source note-taking application" />
|
|
<link
|
|
rel="stylesheet"
|
|
href="/css/bootstrap5.0.2.min.css"
|
|
as="style"
|
|
/>
|
|
<link rel="stylesheet" href="/css/fontawesome-all.min.css?t=1627739182405">
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap"
|
|
rel="stylesheet"
|
|
as="style"
|
|
media="all"
|
|
onload="this.media='all'; this.onload = null"
|
|
/>
|
|
<link rel="stylesheet" href="/css/site.css?t=1627739182405" as="style" />
|
|
<title>Joplin informal encryption and security audit results | Joplin</title>
|
|
|
|
<script
|
|
src="/js/jquery-3.6.0.min.js"
|
|
rel="preload"
|
|
as="script"
|
|
></script>
|
|
</head>
|
|
<body class="website-env-prod">
|
|
<div class="container-fluid generic-template -page" id="main-container">
|
|
|
|
<div class=" navbar-main white-bg" id="nav-section">
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-3">
|
|
<a href="/">
|
|
<img
|
|
src="/images/logo-text-blue.svg"
|
|
alt=""
|
|
id="top-logo"
|
|
width="180"
|
|
/>
|
|
</a>
|
|
</div>
|
|
<div class="col-9 text-right d-none d-md-block">
|
|
<a href="/help/" class="fw500">Help</a>
|
|
<a href="https://discourse.joplinapp.org/" class="fw500">Forum</a>
|
|
<a href="/plans/" class="button-link btn-trans plans-button">Joplin Cloud</a><a class="button-link btn-blue sponsor-button" href="/donate">
|
|
<i class="fas fa-heart heart-full"></i><i class="far fa-heart heart-line"></i> Support us
|
|
</a> </div>
|
|
<div class="col-9 text-right d-block d-md-none">
|
|
<span class="pointer"
|
|
><img
|
|
src="/images/mobile-menu-black-open-icon.png"
|
|
id="open-menu-mobile"
|
|
alt=""
|
|
/></span>
|
|
|
|
|
|
<div id="menu-mobile">
|
|
<div>
|
|
<div class="text-right">
|
|
<img
|
|
src="/images/close-icon.png"
|
|
alt=""
|
|
class="pointer"
|
|
id="close-menu-mobile"
|
|
/>
|
|
</div>
|
|
|
|
<div class="text-center menu-mobile-top">
|
|
<a href="https://discourse.joplinapp.org/" class="fw500 mobile-menu-link">Forum</a>
|
|
<a href="/help/" class="fw500 mobile-menu-link">Help</a>
|
|
</div>
|
|
|
|
<div class="menu-mobile-buttons">
|
|
<a href="/plans/" class="button-link btn-trans plans-button">Joplin Cloud</a><a class="button-link btn-blue sponsor-button" href="/donate">
|
|
<i class="fas fa-heart heart-full"></i><i class="far fa-heart heart-line"></i> Support us
|
|
</a> </div>
|
|
</div>
|
|
|
|
<div id="toc-mobile"><div><ul>
|
|
<li>
|
|
<p>Applications</p>
|
|
<ul>
|
|
<li><a href="/desktop/">Desktop application</a></li>
|
|
<li><a href="/mobile/">Mobile applications</a></li>
|
|
<li><a href="/terminal/">Terminal application</a></li>
|
|
<li><a href="/clipper/">Web Clipper</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Support</p>
|
|
<ul>
|
|
<li><a href="https://discourse.joplinapp.org">Joplin Forum</a></li>
|
|
<li><a href="/markdown/">Markdown Guide</a></li>
|
|
<li><a href="/e2ee/">How to enable end-to-end encryption</a></li>
|
|
<li><a href="/conflict/">What is a conflict?</a></li>
|
|
<li><a href="/debugging/">How to enable debug mode</a></li>
|
|
<li><a href="/rich_text_editor/">About the Rich Text editor limitations</a></li>
|
|
<li><a href="/faq/">FAQ</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Joplin API - Get Started</p>
|
|
<ul>
|
|
<li><a href="/api/overview/">Joplin API Overview</a></li>
|
|
<li><a href="/api/get_started/plugins/">Plugin development</a></li>
|
|
<li><a href="/api/tutorials/toc_plugin/">Plugin tutorial</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Joplin API - References</p>
|
|
<ul>
|
|
<li><a href="https://joplinapp.org/api/references/plugin_api/classes/joplin.html">Plugin API</a></li>
|
|
<li><a href="/api/references/rest_api/">Data API</a></li>
|
|
<li><a href="/api/references/plugin_manifest/">Plugin manifest</a></li>
|
|
<li><a href="/api/references/plugin_loading_rules/">Plugin loading rules</a></li>
|
|
<li><a href="/api/references/plugin_theming/">Plugin theming</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Development</p>
|
|
<ul>
|
|
<li><a href="https://github.com/laurent22/joplin/blob/dev/BUILD.md">How to build the apps</a></li>
|
|
<li><a href="/spec/e2ee/">End-to-end encryption spec</a></li>
|
|
<li><a href="/spec/history/">Note History spec</a></li>
|
|
<li><a href="/spec/sync_lock/">Sync Lock spec</a></li>
|
|
<li><a href="/spec/plugins/">Plugin Architecture spec</a></li>
|
|
<li><a href="/spec/search_sorting/">Search Sorting spec</a></li>
|
|
<li><a href="/spec/server_file_url_format/">Server: File URL Format</a></li>
|
|
<li><a href="/spec/server_delta_sync/">Server: Delta Sync</a></li>
|
|
<li><a href="/spec/server_sharing/">Server: Sharing</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Google Summer of Code 2021</p>
|
|
<ul>
|
|
<li><a href="/gsoc2021/index/">Google Summer of Code 2021</a></li>
|
|
<li><a href="/gsoc2021/pull_request_guidelines/">How to submit a GSoC pull request</a></li>
|
|
<li><a href="/gsoc2021/ideas/">Project Ideas</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>About</p>
|
|
<ul>
|
|
<li><a href="/changelog/">Changelog (Desktop App)</a></li>
|
|
<li><a href="/changelog_cli/">Changelog (CLI App)</a></li>
|
|
<li><a href="/changelog_server/">Changelog (Server)</a></li>
|
|
<li><a href="/stats/">Stats</a></li>
|
|
<li><a href="/donate/">Donate</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div></div>
|
|
|
|
<div>
|
|
<p class="light-blue mobile-menu-link-bottom text-center">
|
|
Copyright © 2016-2021 Laurent Cozic
|
|
<br/>
|
|
<a href="/privacy/" class="fw500">Privacy Policy</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="page-container page-20200406-224254">
|
|
<div class="container">
|
|
<div class="row content-wrapper">
|
|
<div id="toc"><div><ul>
|
|
<li>
|
|
<p>Applications</p>
|
|
<ul>
|
|
<li><a href="/desktop/">Desktop application</a></li>
|
|
<li><a href="/mobile/">Mobile applications</a></li>
|
|
<li><a href="/terminal/">Terminal application</a></li>
|
|
<li><a href="/clipper/">Web Clipper</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Support</p>
|
|
<ul>
|
|
<li><a href="https://discourse.joplinapp.org">Joplin Forum</a></li>
|
|
<li><a href="/markdown/">Markdown Guide</a></li>
|
|
<li><a href="/e2ee/">How to enable end-to-end encryption</a></li>
|
|
<li><a href="/conflict/">What is a conflict?</a></li>
|
|
<li><a href="/debugging/">How to enable debug mode</a></li>
|
|
<li><a href="/rich_text_editor/">About the Rich Text editor limitations</a></li>
|
|
<li><a href="/faq/">FAQ</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Joplin API - Get Started</p>
|
|
<ul>
|
|
<li><a href="/api/overview/">Joplin API Overview</a></li>
|
|
<li><a href="/api/get_started/plugins/">Plugin development</a></li>
|
|
<li><a href="/api/tutorials/toc_plugin/">Plugin tutorial</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Joplin API - References</p>
|
|
<ul>
|
|
<li><a href="https://joplinapp.org/api/references/plugin_api/classes/joplin.html">Plugin API</a></li>
|
|
<li><a href="/api/references/rest_api/">Data API</a></li>
|
|
<li><a href="/api/references/plugin_manifest/">Plugin manifest</a></li>
|
|
<li><a href="/api/references/plugin_loading_rules/">Plugin loading rules</a></li>
|
|
<li><a href="/api/references/plugin_theming/">Plugin theming</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Development</p>
|
|
<ul>
|
|
<li><a href="https://github.com/laurent22/joplin/blob/dev/BUILD.md">How to build the apps</a></li>
|
|
<li><a href="/spec/e2ee/">End-to-end encryption spec</a></li>
|
|
<li><a href="/spec/history/">Note History spec</a></li>
|
|
<li><a href="/spec/sync_lock/">Sync Lock spec</a></li>
|
|
<li><a href="/spec/plugins/">Plugin Architecture spec</a></li>
|
|
<li><a href="/spec/search_sorting/">Search Sorting spec</a></li>
|
|
<li><a href="/spec/server_file_url_format/">Server: File URL Format</a></li>
|
|
<li><a href="/spec/server_delta_sync/">Server: Delta Sync</a></li>
|
|
<li><a href="/spec/server_sharing/">Server: Sharing</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Google Summer of Code 2021</p>
|
|
<ul>
|
|
<li><a href="/gsoc2021/index/">Google Summer of Code 2021</a></li>
|
|
<li><a href="/gsoc2021/pull_request_guidelines/">How to submit a GSoC pull request</a></li>
|
|
<li><a href="/gsoc2021/ideas/">Project Ideas</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>About</p>
|
|
<ul>
|
|
<li><a href="/changelog/">Changelog (Desktop App)</a></li>
|
|
<li><a href="/changelog_cli/">Changelog (CLI App)</a></li>
|
|
<li><a href="/changelog_server/">Changelog (Server)</a></li>
|
|
<li><a href="/stats/">Stats</a></li>
|
|
<li><a href="/donate/">Donate</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div></div>
|
|
|
|
<div class="main-content">
|
|
<div class="alert alert-danger alert-env-dev" role="alert">
|
|
Running in prod mode!
|
|
</div>
|
|
<div class="donate-links">
|
|
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
|
</div>
|
|
<h1>Joplin informal encryption and security audit results<a name="joplin-informal-encryption-and-security-audit-results" href="#joplin-informal-encryption-and-security-audit-results" class="heading-anchor">🔗</a></h1>
|
|
<p>Joplin encryption, and in particular the E2EE system used during synchronisation, was recently audited by Isaac Potoczny-Jones, CEO of <a href="https://tozny.com">Tozny</a> and this is what he had to say:</p>
|
|
<blockquote>
|
|
<p>I was looking through your encryption implementation for Joplin and I have a few comments and concerns. I don't see anything that I *know* is a critical issue, but there are a number of choices and weaknesses that I'd like to lend you some advice about.</p>
|
|
</blockquote>
|
|
<h3>OBC2<a name="obc2" href="#obc2" class="heading-anchor">🔗</a></h3>
|
|
<blockquote>
|
|
<p>OCB2, the chosen multi-block cipher mode has had some weaknesses identified in the last few years. I don't know this mode well since it's not a NIST-approved mode, but here's a paper on the topic. I get the impression it's not considered a good choice anymore. <a href="https://pdfs.semanticscholar.org/bb95/0d82fd390e732f71d8320530994bfb6d2529.pdf">Source</a></p>
|
|
</blockquote>
|
|
<p>We indeed had been notified about this issue by another cryptographer and had been preparing migration to the more secure CCM mode. Migration for this is now complete in all the Joplin clients and a migration tool has been added to the Encryption config screen of the desktop application. In particular you can perform two operations:</p>
|
|
<ul>
|
|
<li>Upgrade the master key: This will convert the master key encryption to CCM</li>
|
|
<li>Re-encryption: With this tool, you can re-encrypt all your data using the new encryption method based on CCM. Please follow the instructions on this screen and note that this process can take quite a bit of time so it's better to plan for it and run it over night. It is not entirely clear how the OBC2 flaw can be exploited but it is best to upgrade your data as soon as possible.</li>
|
|
</ul>
|
|
<h3>Unnecessary key expansions<a name="unnecessary-key-expansions" href="#unnecessary-key-expansions" class="heading-anchor">🔗</a></h3>
|
|
<blockquote>
|
|
<p>Running key expansion on a random key: Your encrypt function uses either 1k or 10k rounds of key derivation. The goal of this is to reduce brute-force attacks against user-chosen passwords. This function appears to me to be used for both password-based key derivation (at 10k rounds) *and* bulk encryption of data from a randomly-generated "master key" (at 1k rounds). The bulk encryption does not need the password expansion since the key is randomly generated (presumably with a cryptographically strong generator). I suspect this could be a major performance issue on the bulk encryption of raw data, so if you're finding encryption slow, this is maybe why.</p>
|
|
</blockquote>
|
|
<p>This is more a performance than a security issue. Indeed, the previous encryption method was using 1,000 key expansion iterations every time a note was encrypted, which is unnecessary since the master key is already secured with 10,000 iterations. As a result the encryption algorithm has been changed to perform only 100 iterations when encrypting notes, which should result in faster encryption and decryption on the desktop, mobile and CLI applications.</p>
|
|
<h3>Unnecessary and potentially insecure master key checksum<a name="unnecessary-and-potentially-insecure-master-key-checksum" href="#unnecessary-and-potentially-insecure-master-key-checksum" class="heading-anchor">🔗</a></h3>
|
|
<blockquote>
|
|
<p>You make and store a checksum of the master password with SHA256 in addition to encrypting it. I expect this is because you need a way to tell if the user's password is correct. I've never seen this done before, and it has me concerned, but I don't know for sure that it's an issue. Thought I'd mention it anyway. <a href="https://crypto.stackexchange.com/questions/61915/can-i-hash-a-secret-key-and-used-the-hash-as-key-id">Source</a>. At least with CCM mode (and I think with OCB2) it shouldn't successfully decrypt if you have the wrong password.</p>
|
|
</blockquote>
|
|
<p>A checksum was previously stored with the master key to verify that it is valid. This could potentially weaken the security of the mater key since, as mentioned in Cryptography StackExchange link, "in the standard model of hash functions there isn't a requirement that hash outputs not have properties that leak information about the input". It was also unnecessary since the decryption algorithm in use would fail if the key is invalid, so the additional checksum was not needed.</p>
|
|
<p>This has also been addressed by the new master key upgrading tool. If you have performed the upgrade, the checksum will be gone from your master key.</p>
|
|
<h3>Encrypting local secrets with a keychain service<a name="encrypting-local-secrets-with-a-keychain-service" href="#encrypting-local-secrets-with-a-keychain-service" class="heading-anchor">🔗</a></h3>
|
|
<blockquote>
|
|
<p>Now I did notice that you cache the plain text password in the database, which is a bit concerning, but I guess the security model of your encryption approach is that it happens during sync, not locally. The generally accepted approach [to store secrets] is to use a keychain service, which is available pretty much on all modern platforms.</p>
|
|
</blockquote>
|
|
<p>Passwords are indeed cached locally, so that you don't have to input it again every time a note needs to be encrypted or decrypted for synchronisation. It is assumed that your local device is secure, which is why for now passwords were cached locally.</p>
|
|
<p>To improve security however, future versions of Joplin will use the system keychain whenever it is available. A <a href="https://github.com/laurent22/joplin/pull/2861">pull request</a> is in progress to add this feature.</p>
|
|
<p>To conclude I'd like to thank Isaac Potoczny-Jones for conducting this audit and revealing these potential security issues. Joplin is now much safer as a result.</p>
|
|
<hr>
|
|
<p>url: <a href="https://www.patreon.com/posts/joplin-informal-35719724">https://www.patreon.com/posts/joplin-informal-35719724</a><br>
|
|
published_at: 2020-04-06T21:42:54.000+00:00</p>
|
|
|
|
<div class="bottom-links">
|
|
<a href="https://github.com/laurent22/joplin/blob/dev/readme/blog/20200406-224254.md">
|
|
<i class="fab fa-github"></i> Improve this doc
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="darkblue-bg">
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-3 d-none d-md-block">
|
|
<img src="/images/logo-text.svg" alt="" width="150" />
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<hr />
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12 col-md-6">
|
|
<img
|
|
src="/images/logo-text.svg"
|
|
width="120"
|
|
class="img-center d-block d-md-none"
|
|
alt=""
|
|
/>
|
|
<br class="d-block d-md-none" />
|
|
<p class="text-center-sm">Copyright © 2016-2021 Laurent Cozic</p>
|
|
</div>
|
|
<div class="col-12 col-md-6 right-links">
|
|
<p class="text-right text-center-sm">
|
|
<a href="https://github.com/laurent22/joplin/" class="github-link"><i class="fab fa-github"></i> GitHub Repository</a>
|
|
<a href="/privacy/">Privacy Policy</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
|
|
<script src="/js/script.js?t=1627739182405"></script>
|
|
|
|
<script>
|
|
if (window.location.hostname !== 'localhost') {
|
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
ga('create', 'UA-103586105-1', 'auto');
|
|
ga('send', 'pageview');
|
|
}
|
|
</script> </body>
|
|
</html>
|