Fix #4: Add encryption details to homepage
This commit is contained in:
parent
0806207b89
commit
a53be04acf
@ -79,8 +79,12 @@ BOWER_INSTALLED_APPS = [
|
|||||||
"https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js",
|
"https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js",
|
||||||
"https://cdn.jsdelivr.net/npm/@mdi/font@7.4.47/css/materialdesignicons.min.css",
|
"https://cdn.jsdelivr.net/npm/@mdi/font@7.4.47/css/materialdesignicons.min.css",
|
||||||
"https://fonts.cdnfonts.com/css/jetbrains-mono",
|
"https://fonts.cdnfonts.com/css/jetbrains-mono",
|
||||||
|
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css",
|
||||||
|
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js",
|
||||||
|
# "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
|
|||||||
@ -34,6 +34,14 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- highlight.js-->
|
||||||
|
<link rel="stylesheet" href="{% static "default.min/index.css" %}">
|
||||||
|
<script src="{% static "highlight.min/index.js" %}"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
hljs.highlightAll()
|
||||||
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<v-app class="font">
|
<v-app class="font">
|
||||||
@ -43,15 +51,192 @@
|
|||||||
<v-container class="container-xs">
|
<v-container class="container-xs">
|
||||||
|
|
||||||
<v-row justify="center">
|
<v-row justify="center">
|
||||||
<v-dialog v-model="dialog" persistent max-width="290">
|
|
||||||
|
<div class="card mt-4 pt-2 ps-lg-2">
|
||||||
|
<h5 class="card-header">{% trans "K356 Project" %}</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
<h2>{% trans "Encryption" %}</h2>
|
||||||
|
<p>{% trans "Your data are secure in an encrypted way, accessible solely by you. The data are purely encrypted and decrypted in the front-end. The back-end has no access to the encryption key, so there is no way for an intruder to decrypt your data." %}</p>
|
||||||
|
|
||||||
|
<div class="accordion" id="enca">
|
||||||
|
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="eh1">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#e1" aria-controls="e1">
|
||||||
|
{% trans "Encryption" %}
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="e1" class="accordion-collapse collapse" aria-labelledby="eh1" data-bs-parent="#enca">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{% blocktrans %}
|
||||||
|
Your data are encrypted using <code>RSA-OAEP</code> algorithm.
|
||||||
|
{% endblocktrans %}
|
||||||
|
|
||||||
|
<pre><code class="language-js">
|
||||||
|
const operations = crypto.subtle
|
||||||
|
|
||||||
|
async encrypt (data) {
|
||||||
|
|
||||||
|
return btoa(arrayBufferToString(await operations.encrypt(
|
||||||
|
{ name: "RSA-OAEP" },
|
||||||
|
publicKey,
|
||||||
|
stringToArrayBuffer(data),
|
||||||
|
)))
|
||||||
|
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="eh2">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#e2" aria-controls="e2">
|
||||||
|
{% trans "Decryption" %}
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="e2" class="accordion-collapse collapse" aria-labelledby="eh2" data-bs-parent="#enca">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{% blocktrans %}
|
||||||
|
Your date are decrypted using the same algorithm, using your own private key.
|
||||||
|
{% endblocktrans %}
|
||||||
|
|
||||||
|
<pre><code class="language-js">
|
||||||
|
const operations = crypto.subtle
|
||||||
|
|
||||||
|
async decrypt (armored_data) {
|
||||||
|
|
||||||
|
return arrayBufferToString(await operations.decrypt(
|
||||||
|
{ name: "RSA-OAEP" },
|
||||||
|
privateKey,
|
||||||
|
stringToArrayBuffer(atob(armored_data))
|
||||||
|
))
|
||||||
|
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="eh3">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#e3" aria-controls="e3">
|
||||||
|
{% trans "Key wrapping" %}
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="e3" class="accordion-collapse collapse" aria-labelledby="eh3" data-bs-parent="#enca">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{% blocktrans %}
|
||||||
|
In order to keep your private/public key pair secret, they are wrapped using a <code>AES-GCM</code> key derived from you password.
|
||||||
|
{% endblocktrans %}
|
||||||
|
|
||||||
|
<pre><code class="language-js">
|
||||||
|
const operations = crypto.subtle
|
||||||
|
|
||||||
|
async wrapKey (key, wrappingKey, iv) => {
|
||||||
|
|
||||||
|
return btoa(arrayBufferToString(await operations.wrapKey(
|
||||||
|
"jwk",
|
||||||
|
key,
|
||||||
|
wrappingKey,
|
||||||
|
{name: "AES-GCM", iv: stringToArrayBuffer(iv)}
|
||||||
|
)))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async unwrapKey (unwrappingKey, armored_jwk_data, iv, args) => {
|
||||||
|
|
||||||
|
return await operations.unwrapKey(
|
||||||
|
"jwk",
|
||||||
|
stringToArrayBuffer(atob(armored_jwk_data)),
|
||||||
|
unwrappingKey,
|
||||||
|
{name: "AES-GCM", iv: stringToArrayBuffer(iv)},
|
||||||
|
{
|
||||||
|
name: "RSA-OAEP",
|
||||||
|
hash: "SHA-256",
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="eh4">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#e4" aria-controls="e3">
|
||||||
|
{% trans "Key derivation" %}
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="e4" class="accordion-collapse collapse" aria-labelledby="eh4" data-bs-parent="#enca">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{% blocktrans %}
|
||||||
|
Your public/private key are not stored as-is. They are wrapped using a <code>AES-GCM</code> key, derivated from your password.
|
||||||
|
A custom salt is used, <i>unique per user</i>, to generate your wrapping key.
|
||||||
|
{% endblocktrans %}
|
||||||
|
|
||||||
|
<pre><code class="language-js">
|
||||||
|
|
||||||
|
const operations = crypto.subtle
|
||||||
|
|
||||||
|
async deriveKeyFromPassphrase(passphrase, salt) => {
|
||||||
|
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const keyFromPassword = await operations.importKey(
|
||||||
|
"raw",
|
||||||
|
encoder.encode(passphrase),
|
||||||
|
"PBKDF2",
|
||||||
|
false,
|
||||||
|
["deriveKey"]
|
||||||
|
)
|
||||||
|
|
||||||
|
return await operations.deriveKey(
|
||||||
|
{
|
||||||
|
name: "PBKDF2",
|
||||||
|
salt: stringToArrayBuffer(salt),
|
||||||
|
iterations: pbkdf2_iterations,
|
||||||
|
hash: "SHA-256",
|
||||||
|
},
|
||||||
|
keyFromPassword,
|
||||||
|
{
|
||||||
|
name: "AES-GCM",
|
||||||
|
length: 256
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
["wrapKey", "unwrapKey"]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card mt-4 pt-2 ps-lg-2">
|
||||||
|
<h5 class="card-header">{% trans "Login / register" %}</h5>
|
||||||
|
<div class="card-body d-flex">
|
||||||
|
<button type="button" class="btn btn-secondary flex-grow-1 flex-shrink-1" @click="dialog = true">{% trans "Click here to login/register" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row justify="center">
|
||||||
|
<v-dialog v-model="dialog" max-width="290" class="modal">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title class="text-h5">
|
<v-card-title class="text-h5">
|
||||||
{% trans "Login" %}
|
{% trans "Login / Register" %}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
|
|
||||||
{% trans "Select login option" %}
|
{% trans "Select option" %}
|
||||||
|
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-list-item-content>
|
<v-list-item-content>
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
{% include "vue/plugins.js" %}
|
{% include "vue/plugins.js" %}
|
||||||
|
|
||||||
|
{% if settings.DEBUG %}
|
||||||
Vue.config.devtools = true
|
Vue.config.devtools = true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter)
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|||||||
@ -12,6 +12,6 @@ const approuter = new Vue({
|
|||||||
vuetify: new Vuetify(),
|
vuetify: new Vuetify(),
|
||||||
el: "#main",
|
el: "#main",
|
||||||
data: {
|
data: {
|
||||||
dialog: true,
|
dialog: false,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user