The Crystal Programming Language Forum

Simple Encrypt + Decrypt?

I come from Laravel background where the following interface exists (docs if you really want to see more):

# example value make by `php artisan key:generate`
# ENV["APL_KEY"] = "base64:dTOymAUpqvF/2tOxnQdakYHuL66HlmkElovGwumCiPE="

struct SimpleEncrypt
  def initialize(
    @key : String = ENV["APP_KEY"], 
    @cypher = AES128)

  def encrypt (data : String) : String
    # encrypts the string

  def decrypt (data : String) : String
    # decrypts the string

e =
value = "any string"
encrypted_value = e.encrypt(value)
value2 = e.decrypt(encrypted_value)
puts value2 == value
# true

I couldn’t find anything in the standard library or for this, but I did find things suited for adjacent topics like password hashing, SSL, certificates, MD5/SHA.

I think this would make a great STD or shard, but I don’t know the primitives for doing this myself.

I found, maybe its code would be useful seems good candidate for your use-case. Especially the example

You can check my simple cli app:


# Encrypt *data*
  def cipher_encrypt(data) : IO::Memory
    cipher ="aes-256-cbc")
    cipher.key = App.cfg.cipher_key
    cipher.iv = App.cfg.cipher_iv
    cipher.update data
    encrypted =

  # Decrypt *data*
  def cipher_decrypt(data) : IO::Memory
    cipher ="aes-256-cbc")
    cipher.key = App.cfg.cipher_key
    cipher.iv = App.cfg.cipher_iv
    cipher.update data
    decrypted =

App.cfg.cipher_* should be replaced (or assigned).

These methods return IO::Memory. Use to_s to get value in String (cipher_encrypt("hello").to_s)


AES encrypt

Forget my example above. I made a more practical and reliable shard :

require "crypt"
require "crypt/crypter"
require "crypt/random"

data = "super secret data"
secret = Crypt.random_string(32)
crypter =

# Data encrypted
encrypted = crypter.encrypt(data)

# Data decrypted
decrypted_bytes = crypter.decrypt(encrypted)

# Decrypted data (Bytes)
puts decrypted_bytes

# Convert Bytes to String

Generate a password:

require "crypt"
require "crypt/bcrypt"

password = Crypt.create_bcrypt_password("super secret")
# => $2a$10$rI4xRiuAN2fyiKwynO6PPuorfuoM4L2PVv6hlnVJEmNLjqcibAfHq

password.verify("wrong secret") # => false
password.verify("super secret") # => true
1 Like

A shard is not necessary for Bcrypt, it is easy enough with the stdlib.
For OpenSSL, I can agree not so much. I hope the API will be revisited and more type safe after the 1.0.