Compare commits
No commits in common. "a53be04acf69cec7791053599994a7374c835f3d" and "63897fb7b09f3970d62c894587a93a760f7e77b9" have entirely different histories.
a53be04acf
...
63897fb7b0
@ -79,12 +79,8 @@ 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",
|
||||||
|
|||||||
@ -67,9 +67,6 @@
|
|||||||
[[ data.item.name ]]
|
[[ data.item.name ]]
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template slot="selection" slot-scope="data">
|
|
||||||
[[ data.item.custom_identifier ]] - [[ data.item.name ]]
|
|
||||||
</template>
|
|
||||||
</v-select>
|
</v-select>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -34,14 +34,6 @@
|
|||||||
}
|
}
|
||||||
</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">
|
||||||
@ -51,192 +43,15 @@
|
|||||||
<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 / Register" %}
|
{% trans "Login" %}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
|
|
||||||
{% trans "Select option" %}
|
{% trans "Select login option" %}
|
||||||
|
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-list-item-content>
|
<v-list-item-content>
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
{% 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: false,
|
dialog: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user