Module: Encryptor

Defined in:
lib/diary-ruby/ext/encryptor.rb

Defined Under Namespace

Classes: Error

Class Method Summary collapse

Class Method Details

.decrypt(document, pwd) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/diary-ruby/ext/encryptor.rb', line 45

def self.decrypt(document, pwd)
  iv, salt, encrypted = unwrap(document)

  Diary.debug "DECRYPT WITH"
  Diary.debug "  iv    #{ Base64.encode64(iv) }"
  Diary.debug "  salt  #{ Base64.encode64(salt) }"
  Diary.debug "  msg   #{ Base64.encode64(encrypted) }"

  ## Decrypt
  cipher = OpenSSL::Cipher.new 'AES-128-CBC'
  cipher.decrypt
  cipher.iv = iv

  salt = salt
  iter = 20000
  key_len = cipher.key_len
  digest = OpenSSL::Digest::SHA256.new

  key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
  cipher.key = key

  decrypted = cipher.update(encrypted)
  decrypted << cipher.final
end

.encrypt(msg, pwd) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/diary-ruby/ext/encryptor.rb', line 20

def self.encrypt(msg, pwd)
  cipher = OpenSSL::Cipher.new 'AES-128-CBC'
  cipher.encrypt

  # random salt
  salt = OpenSSL::Random.random_bytes(16)

  # random initialization vector
  iv = cipher.random_iv

  iter = 20000
  key_len = cipher.key_len
  digest = OpenSSL::Digest::SHA256.new

  key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
  cipher.key = key

  # Now encrypt the data:
  encrypted = cipher.update(msg)
  encrypted << cipher.final

  # And encode final format
  wrap(iv, salt, encrypted)
end

.unwrap(document) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/diary-ruby/ext/encryptor.rb', line 78

def self.unwrap(document)
  if document.is_a?(File)
    document = document.read
  end

  if document.count('|') != 2
    raise Encryptor::Error.new("Document is not a vaild encrypted store.")
  end

  iv64, salt64, encrypted64 = document.split('|')

  iv = Base64.decode64(iv64.to_s.strip)
  salt = Base64.decode64(salt64.to_s.strip)
  encrypted = Base64.decode64(encrypted64.to_s.strip)

  [iv, salt, encrypted]
end

.wrap(iv, salt, encrypted) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/diary-ruby/ext/encryptor.rb', line 70

def self.wrap(iv, salt, encrypted)
  [
    Base64.encode64(iv),
    Base64.encode64(salt),
    Base64.encode64(encrypted)
  ].join('|')
end