sjclWrapper.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //sjcl.js подправлен (убран лишний require, добавлявший +400kb к bundle) и скопирован локально
  2. import sjcl from './sjcl';
  3. //везде недоработки...
  4. sjcl.codec.bytes = {
  5. fromBits: function(arr) {
  6. var out = [], bl = sjcl.bitArray.bitLength(arr), i, tmp;
  7. for (i=0; i<bl/8; i++) {
  8. if ((i&3) === 0) {
  9. tmp = arr[i/4];
  10. }
  11. out.push(tmp >>> 24);
  12. tmp <<= 8;
  13. }
  14. return out;
  15. },
  16. toBits: function(bytes) {
  17. var out = [], i, tmp=0;
  18. for (i=0; i<bytes.length; i++) {
  19. tmp = tmp << 8 | bytes[i];
  20. if ((i&3) === 3) {
  21. out.push(tmp);
  22. tmp = 0;
  23. }
  24. }
  25. if (i&3) {
  26. out.push(sjcl.bitArray.partial(8*(i&3), tmp));
  27. }
  28. return out;
  29. }
  30. };
  31. sjcl.json._add = function(target, src, requireSame) {
  32. if (target === undefined) { target = {}; }
  33. if (src === undefined) { return target; }
  34. var i;
  35. for (i in src) {
  36. if (src.hasOwnProperty(i)) {
  37. if (requireSame && target[i] !== undefined && target[i] !== src[i]) {
  38. throw new sjcl.exception.invalid("required parameter overridden");
  39. }
  40. target[i] = src[i];
  41. }
  42. }
  43. return target;
  44. }
  45. sjcl.encryptArray = function(password, plaintext, params, rp) {
  46. params = params || {};
  47. rp = rp || {};
  48. var j = sjcl.json, p = j._add({ iv: sjcl.random.randomWords(4,0) },
  49. j.defaults), tmp, prp, adata;
  50. j._add(p, params);
  51. adata = p.adata;
  52. if (typeof p.salt === "string") {
  53. p.salt = sjcl.codec.base64.toBits(p.salt);
  54. }
  55. if (typeof p.iv === "string") {
  56. p.iv = sjcl.codec.base64.toBits(p.iv);
  57. }
  58. if (!sjcl.mode[p.mode] ||
  59. !sjcl.cipher[p.cipher] ||
  60. (typeof password === "string" && p.iter <= 100) ||
  61. (p.ts !== 64 && p.ts !== 96 && p.ts !== 128) ||
  62. (p.ks !== 128 && p.ks !== 192 && p.ks !== 256) ||
  63. (p.iv.length < 2 || p.iv.length > 4)) {
  64. throw new sjcl.exception.invalid("json encrypt: invalid parameters");
  65. }
  66. if (typeof password === "string") {
  67. tmp = sjcl.misc.cachedPbkdf2(password, p);
  68. password = tmp.key.slice(0,p.ks/32);
  69. p.salt = tmp.salt;
  70. } else if (sjcl.ecc && password instanceof sjcl.ecc.elGamal.publicKey) {
  71. tmp = password.kem();
  72. p.kemtag = tmp.tag;
  73. password = tmp.key.slice(0,p.ks/32);
  74. }
  75. if (typeof plaintext === "string") {
  76. plaintext = sjcl.codec.utf8String.toBits(plaintext);
  77. }
  78. if (typeof adata === "string") {
  79. p.adata = adata = sjcl.codec.utf8String.toBits(adata);
  80. }
  81. prp = new sjcl.cipher[p.cipher](password);
  82. j._add(rp, p);
  83. rp.key = password;
  84. /* do the encryption */
  85. if (p.mode === "ccm" && sjcl.arrayBuffer && sjcl.arrayBuffer.ccm && plaintext instanceof ArrayBuffer) {
  86. p.ct = sjcl.arrayBuffer.ccm.encrypt(prp, plaintext, p.iv, adata, p.ts);
  87. } else {
  88. p.ct = sjcl.mode[p.mode].encrypt(prp, plaintext, p.iv, adata, p.ts);
  89. }
  90. return p;
  91. }
  92. sjcl.decryptArray = function(password, ciphertext, params) {
  93. params = params || {};
  94. var j = sjcl.json, p = j._add(j._add(j._add({},j.defaults),ciphertext), params, true), ct, tmp, prp, adata=p.adata;
  95. if (typeof p.salt === "string") {
  96. p.salt = sjcl.codec.base64.toBits(p.salt);
  97. }
  98. if (typeof p.iv === "string") {
  99. p.iv = sjcl.codec.base64.toBits(p.iv);
  100. }
  101. if (!sjcl.mode[p.mode] ||
  102. !sjcl.cipher[p.cipher] ||
  103. (typeof password === "string" && p.iter <= 100) ||
  104. (p.ts !== 64 && p.ts !== 96 && p.ts !== 128) ||
  105. (p.ks !== 128 && p.ks !== 192 && p.ks !== 256) ||
  106. (!p.iv) ||
  107. (p.iv.length < 2 || p.iv.length > 4)) {
  108. throw new sjcl.exception.invalid("json decrypt: invalid parameters");
  109. }
  110. if (typeof password === "string") {
  111. tmp = sjcl.misc.cachedPbkdf2(password, p);
  112. password = tmp.key.slice(0,p.ks/32);
  113. p.salt = tmp.salt;
  114. } else if (sjcl.ecc && password instanceof sjcl.ecc.elGamal.secretKey) {
  115. password = password.unkem(sjcl.codec.base64.toBits(p.kemtag)).slice(0,p.ks/32);
  116. }
  117. if (typeof adata === "string") {
  118. adata = sjcl.codec.utf8String.toBits(adata);
  119. }
  120. prp = new sjcl.cipher[p.cipher](password);
  121. /* do the decryption */
  122. if (p.mode === "ccm" && sjcl.arrayBuffer && sjcl.arrayBuffer.ccm && p.ct instanceof ArrayBuffer) {
  123. ct = sjcl.arrayBuffer.ccm.decrypt(prp, p.ct, p.iv, p.tag, adata, p.ts);
  124. } else {
  125. ct = sjcl.mode[p.mode].decrypt(prp, p.ct, p.iv, adata, p.ts);
  126. }
  127. return ct;
  128. }
  129. export default sjcl;