146 lines
4.5 KiB
JavaScript
146 lines
4.5 KiB
JavaScript
//sjcl.js подправлен (убран лишний require, добавлявший +400kb к bundle) и скопирован локально
|
|
import sjcl from './sjcl';
|
|
|
|
//везде недоработки...
|
|
|
|
sjcl.codec.bytes = {
|
|
fromBits: function(arr) {
|
|
var out = [], bl = sjcl.bitArray.bitLength(arr), i, tmp;
|
|
for (i=0; i<bl/8; i++) {
|
|
if ((i&3) === 0) {
|
|
tmp = arr[i/4];
|
|
}
|
|
out.push(tmp >>> 24);
|
|
tmp <<= 8;
|
|
}
|
|
return out;
|
|
},
|
|
toBits: function(bytes) {
|
|
var out = [], i, tmp=0;
|
|
for (i=0; i<bytes.length; i++) {
|
|
tmp = tmp << 8 | bytes[i];
|
|
if ((i&3) === 3) {
|
|
out.push(tmp);
|
|
tmp = 0;
|
|
}
|
|
}
|
|
if (i&3) {
|
|
out.push(sjcl.bitArray.partial(8*(i&3), tmp));
|
|
}
|
|
return out;
|
|
}
|
|
};
|
|
|
|
sjcl.json._add = function(target, src, requireSame) {
|
|
if (target === undefined) { target = {}; }
|
|
if (src === undefined) { return target; }
|
|
var i;
|
|
for (i in src) {
|
|
if (src.hasOwnProperty(i)) {
|
|
if (requireSame && target[i] !== undefined && target[i] !== src[i]) {
|
|
throw new sjcl.exception.invalid("required parameter overridden");
|
|
}
|
|
target[i] = src[i];
|
|
}
|
|
}
|
|
return target;
|
|
}
|
|
|
|
sjcl.encryptArray = function(password, plaintext, params, rp) {
|
|
params = params || {};
|
|
rp = rp || {};
|
|
|
|
var j = sjcl.json, p = j._add({ iv: sjcl.random.randomWords(4,0) },
|
|
j.defaults), tmp, prp, adata;
|
|
j._add(p, params);
|
|
adata = p.adata;
|
|
if (typeof p.salt === "string") {
|
|
p.salt = sjcl.codec.base64.toBits(p.salt);
|
|
}
|
|
if (typeof p.iv === "string") {
|
|
p.iv = sjcl.codec.base64.toBits(p.iv);
|
|
}
|
|
|
|
if (!sjcl.mode[p.mode] ||
|
|
!sjcl.cipher[p.cipher] ||
|
|
(typeof password === "string" && p.iter <= 100) ||
|
|
(p.ts !== 64 && p.ts !== 96 && p.ts !== 128) ||
|
|
(p.ks !== 128 && p.ks !== 192 && p.ks !== 256) ||
|
|
(p.iv.length < 2 || p.iv.length > 4)) {
|
|
throw new sjcl.exception.invalid("json encrypt: invalid parameters");
|
|
}
|
|
|
|
if (typeof password === "string") {
|
|
tmp = sjcl.misc.cachedPbkdf2(password, p);
|
|
password = tmp.key.slice(0,p.ks/32);
|
|
p.salt = tmp.salt;
|
|
} else if (sjcl.ecc && password instanceof sjcl.ecc.elGamal.publicKey) {
|
|
tmp = password.kem();
|
|
p.kemtag = tmp.tag;
|
|
password = tmp.key.slice(0,p.ks/32);
|
|
}
|
|
if (typeof plaintext === "string") {
|
|
plaintext = sjcl.codec.utf8String.toBits(plaintext);
|
|
}
|
|
if (typeof adata === "string") {
|
|
p.adata = adata = sjcl.codec.utf8String.toBits(adata);
|
|
}
|
|
prp = new sjcl.cipher[p.cipher](password);
|
|
|
|
j._add(rp, p);
|
|
rp.key = password;
|
|
|
|
/* do the encryption */
|
|
if (p.mode === "ccm" && sjcl.arrayBuffer && sjcl.arrayBuffer.ccm && plaintext instanceof ArrayBuffer) {
|
|
p.ct = sjcl.arrayBuffer.ccm.encrypt(prp, plaintext, p.iv, adata, p.ts);
|
|
} else {
|
|
p.ct = sjcl.mode[p.mode].encrypt(prp, plaintext, p.iv, adata, p.ts);
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
sjcl.decryptArray = function(password, ciphertext, params) {
|
|
params = params || {};
|
|
|
|
var j = sjcl.json, p = j._add(j._add(j._add({},j.defaults),ciphertext), params, true), ct, tmp, prp, adata=p.adata;
|
|
if (typeof p.salt === "string") {
|
|
p.salt = sjcl.codec.base64.toBits(p.salt);
|
|
}
|
|
if (typeof p.iv === "string") {
|
|
p.iv = sjcl.codec.base64.toBits(p.iv);
|
|
}
|
|
|
|
if (!sjcl.mode[p.mode] ||
|
|
!sjcl.cipher[p.cipher] ||
|
|
(typeof password === "string" && p.iter <= 100) ||
|
|
(p.ts !== 64 && p.ts !== 96 && p.ts !== 128) ||
|
|
(p.ks !== 128 && p.ks !== 192 && p.ks !== 256) ||
|
|
(!p.iv) ||
|
|
(p.iv.length < 2 || p.iv.length > 4)) {
|
|
throw new sjcl.exception.invalid("json decrypt: invalid parameters");
|
|
}
|
|
|
|
if (typeof password === "string") {
|
|
tmp = sjcl.misc.cachedPbkdf2(password, p);
|
|
password = tmp.key.slice(0,p.ks/32);
|
|
p.salt = tmp.salt;
|
|
} else if (sjcl.ecc && password instanceof sjcl.ecc.elGamal.secretKey) {
|
|
password = password.unkem(sjcl.codec.base64.toBits(p.kemtag)).slice(0,p.ks/32);
|
|
}
|
|
if (typeof adata === "string") {
|
|
adata = sjcl.codec.utf8String.toBits(adata);
|
|
}
|
|
prp = new sjcl.cipher[p.cipher](password);
|
|
|
|
/* do the decryption */
|
|
if (p.mode === "ccm" && sjcl.arrayBuffer && sjcl.arrayBuffer.ccm && p.ct instanceof ArrayBuffer) {
|
|
ct = sjcl.arrayBuffer.ccm.decrypt(prp, p.ct, p.iv, p.tag, adata, p.ts);
|
|
} else {
|
|
ct = sjcl.mode[p.mode].decrypt(prp, p.ct, p.iv, adata, p.ts);
|
|
}
|
|
|
|
return ct;
|
|
}
|
|
|
|
export default sjcl; |