~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activesupport/lib/active_support/message_encryptor.rb

  • Committer: Michael Forrest
  • Date: 2010-10-15 16:28:50 UTC
  • Revision ID: michael.forrest@canonical.com-20101015162850-tj2vchanv0kr0dun
refrozeĀ gems

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'openssl'
 
2
 
 
3
module ActiveSupport
 
4
  # MessageEncryptor is a simple way to encrypt values which get stored somewhere 
 
5
  # you don't trust.
 
6
  # 
 
7
  # The cipher text and initialization vector are base64 encoded and returned to you.
 
8
  #
 
9
  # This can be used in situations similar to the MessageVerifier, but where you don't
 
10
  # want users to be able to determine the value of the payload.
 
11
  class MessageEncryptor
 
12
    class InvalidMessage < StandardError; end
 
13
    OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
 
14
 
 
15
    def initialize(secret, cipher = 'aes-256-cbc')
 
16
      @secret = secret
 
17
      @cipher = cipher
 
18
    end
 
19
    
 
20
    def encrypt(value)
 
21
      cipher = new_cipher
 
22
      # Rely on OpenSSL for the initialization vector
 
23
      iv = cipher.random_iv
 
24
      
 
25
      cipher.encrypt 
 
26
      cipher.key = @secret
 
27
      cipher.iv  = iv
 
28
      
 
29
      encrypted_data = cipher.update(Marshal.dump(value)) 
 
30
      encrypted_data << cipher.final
 
31
 
 
32
      [encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--")
 
33
    end
 
34
    
 
35
    def decrypt(encrypted_message)
 
36
      cipher = new_cipher
 
37
      encrypted_data, iv = encrypted_message.split("--").map {|v| ActiveSupport::Base64.decode64(v)}
 
38
      
 
39
      cipher.decrypt
 
40
      cipher.key = @secret
 
41
      cipher.iv  = iv
 
42
 
 
43
      decrypted_data = cipher.update(encrypted_data)
 
44
      decrypted_data << cipher.final
 
45
      
 
46
      Marshal.load(decrypted_data)
 
47
    rescue OpenSSLCipherError, TypeError
 
48
      raise InvalidMessage
 
49
    end
 
50
    
 
51
    def encrypt_and_sign(value)
 
52
      verifier.generate(encrypt(value))
 
53
    end
 
54
    
 
55
    def decrypt_and_verify(value)
 
56
      decrypt(verifier.verify(value))
 
57
    end
 
58
    
 
59
    
 
60
    
 
61
    private 
 
62
      def new_cipher
 
63
        OpenSSL::Cipher::Cipher.new(@cipher)
 
64
      end
 
65
      
 
66
      def verifier
 
67
        MessageVerifier.new(@secret)
 
68
      end
 
69
  end
 
70
end