class DynamicImage::DigestVerifier

DynamicImage Digest Verifier

Usage

verifier = DynamicImage::DigestVerifier.new("super secret!")

digest = verifier.generate("foo")

digest.verify("foo", digest)
# => true
digest.verify("bar", digest)
# => raises DynamicImage::Errors::InvalidSignature

Credit where credit is due: adapted and simplified from ActiveSupport::MessageVerifier, since we don’t need to handle arbitrary data structures and ship the serialized data to the client.

Public Class Methods

new(secret, options = {}) click to toggle source
# File lib/dynamic_image/digest_verifier.rb, line 21
def initialize(secret, options = {})
  @secret = secret
  @digest = options[:digest] || "SHA1"
end

Public Instance Methods

generate(data) click to toggle source

Generates a digest for a string.

# File lib/dynamic_image/digest_verifier.rb, line 27
def generate(data)
  generate_digest(data)
end
verify(data, digest) click to toggle source

Verifies that digest is valid for data. Raises a DynamicImage::Errors::InvalidSignature error if not.

# File lib/dynamic_image/digest_verifier.rb, line 33
def verify(data, digest)
  return true if valid_digest?(data, digest)

  raise DynamicImage::Errors::InvalidSignature
end

Private Instance Methods

generate_digest(data) click to toggle source
# File lib/dynamic_image/digest_verifier.rb, line 51
def generate_digest(data)
  require "openssl" unless defined?(OpenSSL)
  OpenSSL::HMAC.hexdigest(
    OpenSSL::Digest.const_get(@digest).new,
    @secret,
    data
  )
end
secure_compare(str, other) click to toggle source
# File lib/dynamic_image/digest_verifier.rb, line 41
def secure_compare(str, other)
  return false unless str.bytesize == other.bytesize

  l = str.unpack "C#{str.bytesize}"

  res = 0
  other.each_byte { |byte| res |= byte ^ l.shift }
  res.zero?
end
valid_digest?(data, digest) click to toggle source
# File lib/dynamic_image/digest_verifier.rb, line 60
def valid_digest?(data, digest)
  data.present? &&
    digest.present? &&
    secure_compare(digest, generate_digest(data))
end