crypto.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. var CryptoUtils = {
  2. cypher: "AES-GCM",
  3. key: null,
  4. urlSafeKey: null,
  5. initialize: function(key = null) {
  6. if(key === null) {
  7. return this.generateKey();
  8. }
  9. else {
  10. this.urlSafeKey = key;
  11. return this.importKey(this.base64ToArrayBuffer(key));
  12. }
  13. },
  14. generateKey: function() {
  15. var self = this;
  16. return window.crypto.subtle.generateKey(
  17. {
  18. name: this.cypher,
  19. length: 256,
  20. },
  21. true,
  22. ["encrypt", "decrypt"]
  23. ).then(function(k){
  24. self.key = k;
  25. return window.crypto.subtle.exportKey("raw", k)
  26. }).then(function(keydata) {
  27. console.log(keydata);
  28. self.urlSafeKey = self.arrayBufferToBase64(keydata);
  29. }).catch(function(err){
  30. console.error(err)
  31. });
  32. },
  33. encrypt: function(data) {
  34. var self = this;
  35. var iv = window.crypto.getRandomValues(new Uint8Array(12));
  36. return window.crypto.subtle.encrypt(
  37. {
  38. name: this.cypher,
  39. iv: iv,
  40. },
  41. this.key,
  42. data
  43. ).then(function(encrypted){
  44. return new Blob([iv, encrypted], {type: 'application/octet-binary'});
  45. });
  46. },
  47. encryptFilename: function(data) {
  48. var self = this;
  49. var iv = window.crypto.getRandomValues(new Uint8Array(12));
  50. data = this.stringToArrayBuffer(data);
  51. return window.crypto.subtle.encrypt(
  52. {
  53. name: this.cypher,
  54. iv: iv,
  55. },
  56. this.key,
  57. data
  58. ).then(function(encrypted){
  59. var fn = new Uint8Array(iv.length+encrypted.byteLength);
  60. fn.set(iv);
  61. fn.set(new Uint8Array(encrypted), iv.length);
  62. return base32.encode(fn);
  63. });
  64. },
  65. decrypt: function(data) {
  66. var self = this;
  67. return window.crypto.subtle.decrypt(
  68. {
  69. name: this.cypher,
  70. iv: data.slice(0,12),
  71. },
  72. this.key,
  73. data.slice(12)
  74. );
  75. },
  76. decryptFileName: function(data) {
  77. var self = this;
  78. var data = new Uint8Array(base32.decode.asBytes(data)).buffer;
  79. var iv = data.slice(0, 12);
  80. return window.crypto.subtle.decrypt(
  81. {
  82. name: this.cypher,
  83. iv: iv,
  84. },
  85. this.key,
  86. data.slice(12)
  87. );
  88. },
  89. importKey: function(key) {
  90. var self = this;
  91. return window.crypto.subtle.importKey(
  92. "raw",
  93. key,
  94. {
  95. name: self.cypher
  96. },
  97. true,
  98. ["encrypt", "decrypt"]
  99. ).then(function(k){
  100. self.key = k;
  101. });
  102. },
  103. arrayBufferToBase64: function(a) {
  104. return btoa(String.fromCharCode(...new Uint8Array(a)))
  105. },
  106. base64ToArrayBuffer: function(b) {
  107. var str = atob(b);
  108. var buf = new ArrayBuffer(str.length);
  109. var bufView = new Uint8Array(buf);
  110. for (var i=0, strLen=str.length; i<strLen; i++) {
  111. bufView[i] = str.charCodeAt(i);
  112. }
  113. return buf;
  114. },
  115. stringToArrayBuffer: function(str) {
  116. var utf8 = str;
  117. return new Uint8Array(utf8.split('').map(function (item) {
  118. return item.charCodeAt();
  119. })).buffer;
  120. },
  121. arrayBufferToString: function(buf) {
  122. buf = new Uint8Array(buf);
  123. var utf8 = Array.from(buf).map(function (item) {
  124. return String.fromCharCode(item);
  125. }).join('');
  126. return utf8;
  127. }
  128. }