Encode and Encrypt Email Addresses

I want to provide a link for users to unsubscribe to our newsletter.
I don't want the actual email address to show up in the url. So I
would like it something like /unsubscribe/wx313asdf31. What is the
simplest method of encrypting the email to a URL compliant string?

Thanks,
Tom

It might be possible to use another key from that table (perhaps you have an ID column) and use that to unsubscribe users. Is anything like that possible?

TomRossi7 wrote:

I want to provide a link for users to unsubscribe to our newsletter.
I don't want the actual email address to show up in the url.

Why not? If you're only sending the link to that user, there's no
security risk.

So I
would like it something like /unsubscribe/wx313asdf31. What is the
simplest method of encrypting the email to a URL compliant string?

As James suggested, if you've already got the users stored in the DB,
then just use their DB ID or a random unique string that you store in
the DB. If you're not storing e-mail addresses in the DB, then you need
some sort of reversible encryption. Base64 or uuencode would also work
if you don't need high security.

Thanks,
Tom

Best,

  1. I can’t use the actual email address because AOL will redact the address if a complaint is filed.
  2. I can’t use the actual ID, because someone could have a field day unsubscribing people
  3. I could store a random string in the db, but that seems like overkill

Is there a simple way to obfuscate the email address?

Thanks!
Tom

Tom Rossi wrote:

1. I can't use the actual email address because AOL will redact the
address
if a complaint is filed.

Um, what? Not sure I understand.

2. I can't use the actual ID, because someone could have a field day
unsubscribing people
3. I could store a random string in the db, but that seems like
overkill

It's actually very easy to do. Heck, you could even use it as the
primary key.

Is there a simple way to obfuscate the email address?

I already suggested a couple. If all you need is to make it not look
like an e-mail address, though, why don't you just replace the @ with a
/ or something?

Thanks!
Tom

Best,

Hey Tom,

Instead of encrypting/decrypting some data, one typical approach to do
this type of thing is to employ (cryptographic) hashing to verify that
some requested action is valid, as well as to try and discourage
malicious request attempts.

You could try something like:

### in routes:
...
map.connect '/
unsubscribe/:user_id/:dt/:hd', :controller=>'test', :action=>'unsubscribe'
map.connect '/
unsubscribe/:user_id', :controller=>'test', :action=>'unsubscribe'
...

### in controller:
require 'digest/sha2'
...

UNSUBSCRIBE_SECRET = "somelongrandomstring"
UNSUBSCRIBE_URL_PRE = "http://testapp.foo.com/unsubscribe"
...

def unsubscribe
  user_id = params[:user_id].to_i
  dt = params[:dt].to_i
  hd = params[:hd]

  # user doesn't exist in db?
  if user_id < 1 or User.count(:conditions=>["id=?", user_id]) < 1
    # log it and redirect to ....
  end

  # email unsubscribe link to user?
  if dt < 1 or hd.blank?
    dt = Time.now.to_i
    hd = unsubscribe_hd(user_id, dt)
    unsubscribe_url = "#{UNSUBSCRIBE_URL_PRE}/#{user_id}/#{dt}/#{hd}"
    # email url to user and redirect to ....
  end

  # invalid hd?
  expected_hd = unsubscribe_hd(user_id, dt)
  if hd != expected_hd
    # log it and redirect to ....
  end

  # unsubscribe the user and redirect to ...
end
...

protected

def unsubscribe_hd(user_id, dt)
  secret_hd = Digest::SHA256.hexdigest(UNSUBSCRIBE_SECRET)
  return Digest::SHA256.hexdigest("#{user_id}#{dt}#{secret_hd}")
end
...

Jeff

Jeff,

I like the idea of using a real piece of data (the id) and then a hash to validate that its not some random get request! That is a nice, slick, way to avoid complicated encryption or junking up the database. Thanks!

–Tom