Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

crypto.js 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. 'use strict'
  2. class Crypto {
  3. init(options) {
  4. this.crypto = require('crypto')
  5. this.algorithm = options.algorithm || 'aes-256-gcm'
  6. this.hashing = options.hashing || 'sha512'
  7. this.encodeas = options.encodeas || 'hex'
  8. this.iv_size = options.iv_size || 16
  9. this.at_size = options.at_size || 16
  10. this.key_size = options.key_size || 32
  11. this.secret = this._deriveKey(options.secret) || false
  12. }
  13. set(plaintext) {
  14. const iv = this.crypto.randomBytes(this.iv_size).toString(this.encodeas)
  15. const aad = this._digest(
  16. iv + this.secret,
  17. JSON.stringify(plaintext),
  18. this.hashing,
  19. this.encodeas
  20. )
  21. const ct = this._encrypt(
  22. this.secret,
  23. JSON.stringify(plaintext),
  24. this.algorithm,
  25. this.encodeas,
  26. iv,
  27. aad
  28. )
  29. const hmac = this._digest(this.secret, ct.ct, this.hashing, this.encodeas)
  30. const obj = JSON.stringify({
  31. hmac,
  32. ct: ct.ct,
  33. at: ct.at,
  34. aad,
  35. iv,
  36. })
  37. return obj
  38. }
  39. get(ciphertext) {
  40. let ct
  41. if (ciphertext) {
  42. try {
  43. ct = JSON.parse(ciphertext)
  44. } catch (err) {
  45. ct = ciphertext
  46. }
  47. }
  48. const hmac = this._digest(this.secret, ct.ct, this.hashing, this.encodeas)
  49. if (hmac !== ct.hmac) {
  50. throw new Error('Encrypted session was tampered with!')
  51. }
  52. if (ct.at) {
  53. ct.at = Buffer.from(ct.at)
  54. }
  55. const pt = this._decrypt(
  56. this.secret,
  57. ct.ct,
  58. this.algorithm,
  59. this.encodeas,
  60. ct.iv,
  61. ct.at,
  62. ct.aad
  63. )
  64. return pt
  65. }
  66. _digest(key, obj, hashing, encodeas) {
  67. const hmac = this.crypto.createHmac(this.hashing, key)
  68. hmac.setEncoding(encodeas)
  69. hmac.write(obj)
  70. hmac.end()
  71. return hmac.read().toString(encodeas)
  72. }
  73. _encrypt(key, pt, algo, encodeas, iv, aad) {
  74. const cipher = this.crypto.createCipheriv(algo, key, iv, {
  75. authTagLength: this.at_size,
  76. })
  77. let ct
  78. let at
  79. if (aad) {
  80. try {
  81. cipher.setAAD(Buffer.from(aad), {
  82. plaintextLength: Buffer.byteLength(pt),
  83. })
  84. } catch (err) {
  85. throw err
  86. }
  87. }
  88. ct = cipher.update(pt, 'utf8', encodeas)
  89. ct += cipher.final(encodeas)
  90. try {
  91. at = cipher.getAuthTag()
  92. } catch (err) {
  93. throw err
  94. }
  95. return at ? { ct, at } : { ct }
  96. }
  97. _decrypt(key, ct, algo, encodeas, iv, at, aad) {
  98. const cipher = this.crypto.createDecipheriv(algo, key, iv)
  99. let pt
  100. if (at) {
  101. try {
  102. cipher.setAuthTag(Buffer.from(at))
  103. } catch (err) {
  104. throw err
  105. }
  106. }
  107. if (aad) {
  108. try {
  109. cipher.setAAD(Buffer.from(aad), {
  110. plaintextLength: Buffer.byteLength(ct),
  111. })
  112. } catch (err) {
  113. throw err
  114. }
  115. }
  116. pt = cipher.update(ct, encodeas, 'utf8')
  117. pt += cipher.final('utf8')
  118. return pt
  119. }
  120. _deriveKey(secret) {
  121. const hash = this.crypto.createHash(this.hashing)
  122. hash.update(secret)
  123. const salt = hash.digest(this.encodeas).substr(0, 16)
  124. const key = this.crypto.pbkdf2Sync(secret, salt, 10000, 64, this.hashing)
  125. return key.toString(this.encodeas).substr(0, this.key_size)
  126. }
  127. }
  128. module.exports = new Crypto()