Skip to content

Instantly share code, notes, and snippets.

@rubencaro
Last active May 7, 2020 20:59
Show Gist options
  • Save rubencaro/9545060 to your computer and use it in GitHub Desktop.
Save rubencaro/9545060 to your computer and use it in GitHub Desktop.
Reversible encryption for url json data
require 'openssl'
require 'digest/sha1'
require 'base64'
require 'json'
def go_demo!
key = Digest::SHA1.hexdigest("clave1")[0..15] # 16bytes => 128bits
iv = 'clave2 con chicha'[0..15] # 16bytes forced
data = { esto: 'es', un: 'hash', en: 'ruby' }
jsondata = data.to_json
puts "json: #{jsondata}"
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
cipher.encrypt
cipher.key = key
cipher.iv = iv
encrypted = cipher.update(jsondata)
encrypted << cipher.final
coded = CGI.escape( Base64.encode64(encrypted) )
puts "coded: #{coded}"
decoded = Base64.decode64( CGI.unescape(coded) )
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
cipher.decrypt
cipher.key = key
cipher.iv = iv
decrypted = cipher.update(decoded)
decrypted << cipher.final
recovered_data = JSON.parse decrypted
puts "recovered_data: #{recovered_data}"
end
=begin
running it:
> go_demo!
json: {"esto":"es","un":"hash","en":"ruby"}
coded: U%2F%2FKhwcnrtY9qrW18t9vD1E0t58Di1I8yTVbaG6MLLUTc9jl%2Bd4YELatStTU%0Akip7%0A
recovered_data: {"esto"=>"es", "un"=>"hash", "en"=>"ruby"}
=end
import base64
import hashlib
import json
import urllib
from Crypto.Cipher import AES
def go_demo():
key = hashlib.sha1('clave1').hexdigest()[0:16] # 16bytes => 128bits
iv = 'clave2 con chicha'[0:16] # 16bytes forced
data = { 'esto':'es', 'un':'hash', 'en':'python' }
jsondata = json.dumps(data)
print "json: %s" % jsondata
# PKCS#7 padding
padding_len = 16 - (len(jsondata) % 16)
jsondata += chr(padding_len) * padding_len
cipher = AES.new(key, AES.MODE_CBC, iv) # AES-128-CBC
encrypted = cipher.encrypt( jsondata )
coded = urllib.quote_plus( base64.b64encode(encrypted) )
print "coded: %s" % coded
decoded = base64.b64decode( urllib.unquote_plus(coded) )
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(decoded)
# remove padding
padding_len = ord(decrypted[-1])
decrypted = decrypted[:-padding_len]
recovered_data = json.loads(decrypted)
print "recovered_data: %s" % str(recovered_data)
"""
Running it:
>go_demo()
json: {"esto": "es", "en": "python", "un": "hash"}
coded: zME4eM7HXy1Vec659edWqeR1xnmjVEKIpsD43YKFS2%2BqVfPzkxB5yHuiYs07S2c0
recovered_data: {u'esto': u'es', u'en': u'python', u'un': u'hash'}
"""
defmodule Cipher do
@doc """
Gets a usable string from a binary crypto hash
"""
def hexdigest(binary) do
:lists.flatten(for b <- :erlang.binary_to_list(binary), do: :io_lib.format("~2.16.0B", [b]))
|> :string.to_lower
|> List.to_string
end
@doc """
Pad given string until its length is divisible by 16.
It uses PKCS#7 padding.
"""
def pad(str) do
len = String.length(str)
pad_len = 16 - rem(len, 16)
String.ljust(str, len + pad_len, pad_len) # PKCS#7 padding
end
@doc "Remove PKCS#7 padding from given string."
def depad(str) do
<<last>> = String.last str
String.rstrip str, last
end
def go_demo() do
key = :crypto.hash(:sha, "clave1") |> hexdigest |> String.slice(0,16)
iv = "clave2 con chicha" |> String.slice(0,16)
data = "{\"esto\": \"es\", \"en\": \"python\", \"un\": \"hash\"}"
encrypted = :crypto.aes_cbc_128_encrypt key, iv, pad(data)
coded = encrypted |> Base.encode64 |> URI.encode_www_form
{:ok, decoded} = coded |> URI.decode_www_form |> Base.decode64
decrypted = :crypto.aes_cbc_128_decrypt key, iv, decoded |> depad
# decrypted == data
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment