Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
amrani
jio
Commits
0b8bd163
Commit
0b8bd163
authored
May 07, 2018
by
amrani
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
adding friedly user password to cryptostorage
parent
d963b0a5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
244 additions
and
108 deletions
+244
-108
Gruntfile.js
Gruntfile.js
+1
-0
src/jio.storage/cryptstorage.js
src/jio.storage/cryptstorage.js
+216
-92
src/jio.storage/dropboxstorage.js
src/jio.storage/dropboxstorage.js
+7
-4
test/jio.storage/cryptstorage.tests.js
test/jio.storage/cryptstorage.tests.js
+20
-12
No files found.
Gruntfile.js
View file @
0b8bd163
...
...
@@ -75,6 +75,7 @@ module.exports = function (grunt) {
indent
:
2
,
maxerr
:
3
,
predef
:
[
'
DataView
'
,
'
define
'
,
'
exports
'
,
'
require
'
,
...
...
src/jio.storage/cryptstorage.js
View file @
0b8bd163
...
...
@@ -12,20 +12,17 @@
/*
The cryptography system used by this storage is AES-GCM.
Here is an example of how to generate a key to the json format:
Here is an example of how to generate a strong user key :
go to the website : https://randomkeygen.com/ pike a key and memorize it
let suppose the key choseen is "Hwm0jPAmQC" then :
return new RSVP.Queue()
.push(function () {
return crypto.subtle.generateKey({name: "AES-GCM", length: 256},
true, ["encrypt", "decrypt"]);
})
.push(function (key) {
return crypto.subtle.exportKey("jwk", key);
})
.push(function (json_key) {
var jio = jIO.createJIO({
type: "crypt",
key:
json_key
,
key:
"Hwm0jPAmQC"
,
sub_storage: {storage_definition}
});
});
...
...
@@ -43,22 +40,142 @@
var
MIME_TYPE
=
"
application/x-jio-aes-gcm-encryption
"
;
//used unibabel.js for converting function
function
hexToBuffer
(
hex
)
{
// Xxxx use Uint8Array or ArrayBuffer or DataView
var
i
,
byteLen
=
hex
.
length
/
2
,
arr
,
j
=
0
;
if
(
byteLen
!==
parseInt
(
byteLen
,
10
))
{
throw
new
Error
(
"
Invalid hex length '
"
+
hex
.
length
+
"
'
"
);
}
arr
=
new
Uint8Array
(
byteLen
);
for
(
i
=
0
;
i
<
byteLen
;
i
+=
1
)
{
arr
[
i
]
=
parseInt
(
hex
[
j
]
+
hex
[
j
+
1
],
16
);
j
+=
2
;
}
return
arr
;
}
function
utf8ToBinaryString
(
str
)
{
var
escstr
=
encodeURIComponent
(
str
),
// replaces any uri escape sequence, such as %0A,
// with binary escape, such as 0x0A
binstr
=
escstr
.
replace
(
/%
([
0-9A-F
]{2})
/g
,
function
(
p1
)
{
return
String
.
fromCharCode
(
parseInt
(
p1
,
16
));
});
return
binstr
;
}
function
binaryStringToBuffer
(
binstr
)
{
var
buf
;
if
(
"
undefined
"
!==
Uint8Array
)
{
buf
=
new
Uint8Array
(
binstr
.
length
);
}
else
{
buf
=
[];
}
Array
.
prototype
.
forEach
.
call
(
binstr
,
function
(
ch
,
i
)
{
buf
[
i
]
=
ch
.
charCodeAt
(
0
);
});
return
buf
;
}
function
utf8ToBuffer
(
str
)
{
var
binstr
=
utf8ToBinaryString
(
str
),
buf
=
binaryStringToBuffer
(
binstr
);
return
buf
;
}
function
hex
(
buffer
)
{
var
hexCodes
=
[],
view
=
new
DataView
(
buffer
),
i
,
value
,
stringValue
,
padding
,
paddedValue
;
for
(
i
=
0
;
i
<
view
.
byteLength
;
i
+=
4
)
{
// Using getUint32 reduces the number
//of iterations needed (we process 4 bytes each time)
value
=
view
.
getUint32
(
i
);
// toString(16) will give the hex representation
//of the number without padding
stringValue
=
value
.
toString
(
16
);
// We use concatenation and slice for padding
padding
=
'
00000000
'
;
paddedValue
=
(
padding
+
stringValue
).
slice
(
-
padding
.
length
);
hexCodes
.
push
(
paddedValue
);
}
}
function
sha256
(
str
)
{
// We transform the string into an arraybuffer.
return
crypto
.
subtle
.
digest
(
"
SHA-256
"
,
utf8ToBuffer
(
str
))
.
then
(
function
(
hash
)
{
return
hex
(
hash
);
});
}
//function for JIO.js substorage
//API for using String Key form user
function
CryptStorage
(
spec
)
{
this
.
_key
=
spec
.
key
;
this
.
_jsonKey
=
true
;
this
.
_sub_storage
=
jIO
.
createJIO
(
spec
.
sub_storage
);
if
(
spec
.
key
!==
undefined
&&
spec
.
key
!==
null
&&
typeof
spec
.
key
===
'
string
'
)
{
this
.
_key
=
spec
.
key
;
this
.
_userkey
=
true
;
//hash the value of spec.key so if some one try to get it back
sha256
(
spec
.
key
).
then
(
function
(
digest
)
{
spec
.
key
=
digest
;
});
this
.
_sub_storage
=
jIO
.
createJIO
(
spec
.
sub_storage
);
}
else
{
spec
.
key
=
null
;
this
.
_userkey
=
false
;
this
.
_key
=
null
;
this
.
_sub_storage
=
jIO
.
createJIO
(
spec
.
sub_storage
);
}
}
function
convertKey
(
that
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
crypto
.
subtle
.
importKey
(
"
jwk
"
,
that
.
_key
,
"
AES-GCM
"
,
false
,
[
"
encrypt
"
,
"
decrypt
"
]);
var
passphraseKey
=
utf8ToBuffer
(
that
.
_key
);
return
window
.
crypto
.
subtle
.
importKey
(
"
raw
"
,
passphraseKey
,
{
name
:
"
PBKDF2
"
},
false
,
[
"
deriveBits
"
,
"
deriveKey
"
]
);
})
.
push
(
function
(
key
)
{
return
window
.
crypto
.
subtle
.
deriveKey
({
"
name
"
:
"
PBKDF2
"
,
"
salt
"
:
hexToBuffer
(
"
6f0904840608c09ae18c131542fbd1bd
"
),
"
iterations
"
:
1000
,
//we can add iteration number but slow CPU will freez
"
hash
"
:
"
SHA-256
"
},
key
,
{
"
name
"
:
"
AES-GCM
"
,
"
length
"
:
256
},
false
,
[
"
encrypt
"
,
"
decrypt
"
]);
})
.
push
(
function
(
res
)
{
that
.
_key
=
res
;
that
.
_
jsonK
ey
=
false
;
that
.
_
userk
ey
=
false
;
return
;
});
}
...
...
@@ -97,84 +214,91 @@
CryptStorage
.
prototype
.
putAttachment
=
function
(
id
,
name
,
blob
)
{
var
initializaton_vector
=
crypto
.
getRandomValues
(
new
Uint8Array
(
12
)),
that
=
this
;
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
that
.
_jsonKey
===
true
)
{
return
convertKey
(
that
);
}
return
;
})
.
push
(
function
()
{
return
jIO
.
util
.
readBlobAsDataURL
(
blob
);
})
.
push
(
function
(
dataURL
)
{
//string->arraybuffer
var
strLen
=
dataURL
.
target
.
result
.
length
,
buf
=
new
ArrayBuffer
(
strLen
),
bufView
=
new
Uint8Array
(
buf
),
i
;
dataURL
=
dataURL
.
target
.
result
;
for
(
i
=
0
;
i
<
strLen
;
i
+=
1
)
{
bufView
[
i
]
=
dataURL
.
charCodeAt
(
i
);
}
return
crypto
.
subtle
.
encrypt
({
name
:
"
AES-GCM
"
,
iv
:
initializaton_vector
},
that
.
_key
,
buf
);
})
.
push
(
function
(
coded
)
{
var
blob
=
new
Blob
([
initializaton_vector
,
coded
],
{
type
:
MIME_TYPE
});
return
that
.
_sub_storage
.
putAttachment
(
id
,
name
,
blob
);
});
if
(
that
.
_key
!==
null
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
that
.
_userkey
===
true
)
{
return
convertKey
(
that
);
}
return
;
})
.
push
(
function
()
{
return
jIO
.
util
.
readBlobAsDataURL
(
blob
);
})
.
push
(
function
(
dataURL
)
{
//string->arraybuffer
var
strLen
=
dataURL
.
target
.
result
.
length
,
buf
=
new
ArrayBuffer
(
strLen
),
bufView
=
new
Uint8Array
(
buf
),
i
;
dataURL
=
dataURL
.
target
.
result
;
for
(
i
=
0
;
i
<
strLen
;
i
+=
1
)
{
bufView
[
i
]
=
dataURL
.
charCodeAt
(
i
);
}
return
crypto
.
subtle
.
encrypt
({
name
:
"
AES-GCM
"
,
iv
:
initializaton_vector
},
that
.
_key
,
buf
);
})
.
push
(
function
(
coded
)
{
var
blob
=
new
Blob
([
initializaton_vector
,
coded
],
{
type
:
MIME_TYPE
});
return
that
.
_sub_storage
.
putAttachment
(
id
,
name
,
blob
);
});
}
//if the password is not a string or null or undefined
//we do not crypt data
return
that
.
_sub_storage
.
putAttachment
(
id
,
name
,
blob
);
};
CryptStorage
.
prototype
.
getAttachment
=
function
(
id
,
name
)
{
var
that
=
this
;
return
that
.
_sub_storage
.
getAttachment
(
id
,
name
)
.
push
(
function
(
blob
)
{
if
(
blob
.
type
!==
MIME_TYPE
)
{
return
blob
;
}
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
that
.
_jsonKey
===
true
)
{
return
convertKey
(
that
);
}
return
;
})
.
push
(
function
()
{
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
})
.
push
(
function
(
coded
)
{
var
initializaton_vector
;
coded
=
coded
.
target
.
result
;
initializaton_vector
=
new
Uint8Array
(
coded
.
slice
(
0
,
12
));
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
crypto
.
subtle
.
decrypt
({
name
:
"
AES-GCM
"
,
iv
:
initializaton_vector
},
that
.
_key
,
coded
.
slice
(
12
));
})
.
push
(
function
(
arr
)
{
//arraybuffer->string
arr
=
String
.
fromCharCode
.
apply
(
null
,
new
Uint8Array
(
arr
));
return
jIO
.
util
.
dataURItoBlob
(
arr
);
})
.
push
(
undefined
,
function
(
error
)
{
if
(
error
instanceof
DOMException
)
{
return
blob
;
}
throw
error
;
});
});
});
if
(
that
.
_key
!==
null
)
{
return
that
.
_sub_storage
.
getAttachment
(
id
,
name
)
.
push
(
function
(
blob
)
{
if
(
blob
.
type
!==
MIME_TYPE
)
{
return
blob
;
}
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
if
(
that
.
_userkey
===
true
)
{
return
convertKey
(
that
);
}
return
;
})
.
push
(
function
()
{
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
})
.
push
(
function
(
coded
)
{
var
initializaton_vector
;
coded
=
coded
.
target
.
result
;
initializaton_vector
=
new
Uint8Array
(
coded
.
slice
(
0
,
12
));
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
crypto
.
subtle
.
decrypt
({
name
:
"
AES-GCM
"
,
iv
:
initializaton_vector
},
that
.
_key
,
coded
.
slice
(
12
));
})
.
push
(
function
(
arr
)
{
//arraybuffer->string
arr
=
String
.
fromCharCode
.
apply
(
null
,
new
Uint8Array
(
arr
));
return
jIO
.
util
.
dataURItoBlob
(
arr
);
})
.
push
(
undefined
,
function
(
error
)
{
if
(
error
instanceof
DOMException
)
{
return
blob
;
}
throw
error
;
});
});
});
}
//if the password is not a string or null or undefined
//we do not crypt data
return
that
.
_sub_storage
.
getAttachment
(
id
,
name
);
};
CryptStorage
.
prototype
.
removeAttachment
=
function
()
{
...
...
@@ -189,4 +313,4 @@
jIO
.
addStorage
(
'
crypt
'
,
CryptStorage
);
}(
jIO
,
RSVP
,
DOMException
,
Blob
,
crypto
,
Uint8Array
,
ArrayBuffer
));
}(
jIO
,
RSVP
,
DOMException
,
Blob
,
crypto
,
Uint8Array
,
ArrayBuffer
));
\ No newline at end of file
src/jio.storage/dropboxstorage.js
View file @
0b8bd163
...
...
@@ -255,12 +255,15 @@
})
.
push
(
function
(
evt
)
{
if
(
evt
.
target
.
response
instanceof
Blob
)
{
return
evt
.
target
.
response
;
//create a new blob with type AES-GCM to decrypt back
var
cryptblob
=
new
Blob
([
evt
.
target
.
response
],
{
type
:
"
application/x-jio-aes-gcm-encryption
"
});
return
cryptblob
;
}
return
new
Blob
(
[
evt
.
target
.
responseText
],
{
"
type
"
:
evt
.
target
.
getResponseHeader
(
'
Content-Type
'
)
||
"
application/octet-stream
"
}
{
"
type
"
:
"
application/x-jio-aes-gcm-encryption
"
}
// evt.target.getResponseHeader('Content-Type') ||
);
},
function
(
error
)
{
if
(
error
.
target
!==
undefined
&&
error
.
target
.
status
===
409
)
{
...
...
@@ -325,4 +328,4 @@
jIO
.
addStorage
(
'
dropbox
'
,
DropboxStorage
);
}(
jIO
,
RSVP
,
Blob
,
JSON
));
}(
jIO
,
RSVP
,
Blob
,
JSON
));
\ No newline at end of file
test/jio.storage/cryptstorage.tests.js
View file @
0b8bd163
...
...
@@ -11,9 +11,15 @@
equal
=
QUnit
.
equal
,
throws
=
QUnit
.
throws
,
module
=
QUnit
.
module
,
key
=
{
"
alg
"
:
"
A256GCM
"
,
"
ext
"
:
true
,
"
k
"
:
"
seeaLzpu8dHG07bO2ANH2GywbTqs_zrs4Vq8zmtYeE4
"
,
"
key_ops
"
:
[
"
encrypt
"
,
"
decrypt
"
],
"
kty
"
:
"
oct
"
};
key
=
"
password
"
,
key_generated_by_password
=
{
"
alg
"
:
"
A256GCM
"
,
"
ext
"
:
true
,
"
k
"
:
"
wBHHU4Es8IqMCnH03Jxhc1ZTQN7hzo6GkCNnbA_0kjI
"
,
"
key_ops
"
:
[
"
encrypt
"
,
"
decrypt
"
],
"
kty
"
:
"
oct
"
};
/////////////////////////////////////////////////////////////////
// Custom test substorage definition
...
...
@@ -362,8 +368,7 @@
test
(
"
return substorage getattachment if not data url
"
,
function
()
{
var
id
=
"
/
"
,
attachment
=
"
stringattachment
"
,
blob
=
new
Blob
([
'
foo
'
],
{
type
:
'
application/x-jio-aes-gcm-encryption
'
});
blob
=
new
Blob
([
'
foo
'
],
{
type
:
'
application/x-jio-aes-gcm-encryption
'
});
Storage200
.
prototype
.
getAttachment
=
function
(
arg1
,
arg2
)
{
equal
(
arg1
,
id
,
"
getAttachment 200 called
"
);
...
...
@@ -390,10 +395,12 @@
var
id
=
"
/
"
,
attachment
=
"
stringattachment
"
,
value
=
"
azertyuio
\n
pàç_è-('é&
"
,
tocheck
=
"
data:application/x-jio-aes-gcm-encryption;base64
"
+
"
,+p/Ho+KgGHZC2zDLMbQQS2tXcsy0g+Ho41VZnlPEkXdmG9zm36c8iLCkv
"
+
"
lanyWCN510NK4hj1EgWQ6WrLS5pCmA/yeAWh+HyfPkYKDRHVBl6+Hxd53I
"
+
"
TmiWQ6Vix2jaIQg==
"
,
tocheck
=
"
data:application/x-jio-aes-gcm-encryption
"
+
"
;base64,2lHQ9xpJJ9qd81DxZEyd1LICtaV3XD+I2d5cp137L4NQC
"
+
"
vdkasBaFkPUE5XiY88g5z0oN9dcDASfChmvgqrkDExKS+zVglvVVs
"
+
"
CyECYorZ5fwgMCWAL5vUNCCaqhFVFyng==
"
,
blob
=
jIO
.
util
.
dataURItoBlob
(
tocheck
);
...
...
@@ -427,6 +434,7 @@
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.putAttachment
/////////////////////////////////////////////////////////////////
...
...
@@ -445,7 +453,7 @@
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
crypto
.
subtle
.
importKey
(
"
jwk
"
,
key
,
return
crypto
.
subtle
.
importKey
(
"
jwk
"
,
key
_generated_by_password
,
"
AES-GCM
"
,
false
,
[
"
decrypt
"
]);
})
.
push
(
function
(
res
)
{
...
...
@@ -460,11 +468,10 @@
coded
=
coded
.
target
.
result
;
iv
=
new
Uint8Array
(
coded
.
slice
(
0
,
12
));
return
crypto
.
subtle
.
decrypt
({
name
:
"
AES-GCM
"
,
iv
:
iv
},
return
crypto
.
subtle
.
decrypt
({
name
:
"
AES-GCM
"
,
iv
:
iv
},
decryptKey
,
coded
.
slice
(
12
));
})
.
push
(
function
(
arr
)
{
arr
=
String
.
fromCharCode
.
apply
(
null
,
new
Uint8Array
(
arr
));
equal
(
arr
,
...
...
@@ -492,6 +499,7 @@
return
decodeAES
(
arg3
);
};
stop
();
expect
(
7
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment