# Krypt # Non-boring Ruby # Cryptography ### RubyConf Brazil 2013
# @abstractj
# Paranoid about infrastructure security
# Passionate about # cryptography
# But just a wannabe
# Also did Java ![](img/java_evil.png)
# and currently I still do
# Please don't judge!
#DISCLAIMER
#Crypto was #supposed #to be simple
# But most part of the time is like ![](img/doing_crypto.gif)
# You are not alone # Is hard to get it right
# But is present into our lives

Secure communication

Encrypted storage

Digital signatures

Digital cash

Anonymity

Elections

# Even if you don't care
# And if you don't
# Crypto can lead you to fail

Debian

custom

OpenSSL

Yahoo

Guessable

security

questions

Evernote

64 bit RC2

encryption

# Crypto is a key weapon

Not joking

Just google for

"encryption export rules"

People get hurt

# Crypto mostly sucks
"Security is the jar jar binks of software development" - Martin Boßlet

People will

intentionally

skip this

if possible

# Why should I care about it?

DDoS

Man-in-the-middle

attack

# But hey # abstractj!
# I was into SSL bizz # before it was cool!

sslstrip

still works

CRIME

BEAST

# Really?
# Everyone else, have some dark, # embarrassing secret
# If you don't care about your data….

Obama will do

PRISM & XKeyscore

Your cloud backup!

# Even if # companies properly # encrypt their data

At some point they might be

enforced

to provide

information

# It sounds crazy, eh?!

Snowden,

anyone?

# What can # we do?
# Don't trust # third parties!

Or into

self-proclaimed

military-grade encryption

# Encrypt your shit
# *Ok, got it. Let's hire a crypto analyst*
# Most part of the time you are at your own
# And let me tell the ugly truth
# Crypto books can be...

GOOD

EVIL

Caesar cipher

Vigener

Rotor machines

Lorenz Cipher Machine

Symmetric ciphers

Asymmetric ciphers

Substitution ciphers

PRNGs Hashs OTP DES
# And won't # make you a # cryptographer
# If you think you know too much about crypto

Don't play the hero

# Implementing your own # crypto is a # terrible idea

DON'T

Implement your

own crypto

For this reason NIST exists

CWE

# *Ok I got your point*
# Can we talk about code now?! # Please!
# How crypto is done nowadays ## OpenSSL ## Java security & friends
# Full control

GOOD

BAD

# A few examples # for any # language
#Use of a One-Way Hash without a Salt ## CWE-759
# Use of a One-Way Hash # with a # Predictable Salt ## CWE-760

CWE-760


  password = "strong"
  digest = OpenSSL::Digest::SHA256.new

  salt = password # FAIL
  len = digest.digest_length
  iter = 20000
  # API design FAIL
  pbkdf2 = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, len, digest)
  puts "#{pbkdf2.unpack("H*").first}"

CWE-760


    password = "" # FAIL
    digest = OpenSSL::Digest::SHA256.new

    salt = password #This is really bad
    len = digest.digest_length
    iter = 20000

    pbkdf2 = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, len, digest)
    puts "#{pbkdf2.unpack("H*").first}"

CWE-760


    digest = OpenSSL::Digest::SHA256.new

    salt = OpenSSL::Random.random_bytes(16) #YAY!
    len = digest.digest_length
    iter = 20000

    pbkdf2 = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, len, digest)
    puts "#{pbkdf2.unpack("H*").first}"
# Password Hash # With # Insufficient ## Computational Effort ## CWE-916

CWE-916


    digest = OpenSSL::Digest::SHA256.new

    salt = OpenSSL::Random.random_bytes(16) # YAY!
    len = digest.digest_length
    # Hashcat can break it
    iter = 1 
    pbkdf2 = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, len, digest)
    puts "#{pbkdf2.unpack("H*").first}"

CWE-916


    digest = OpenSSL::Digest::SHA256.new

    salt = OpenSSL::Random.random_bytes(16) # YAY!
    len = digest.digest_length
    # It depends on what machines are involved
    iter = 100000000 
    pbkdf2 = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, len, digest)
    puts "#{pbkdf2.unpack("H*").first}"

CWE-916


    digest = OpenSSL::Digest::SHA256.new

    salt = OpenSSL::Random.random_bytes(16) # YAY!
    len = digest.digest_length
    iter = 20000 
    pbkdf2 = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, len, digest)
    puts "#{pbkdf2.unpack("H*").first}"
# Use of a Broken or Risky # Cryptographic Algorithm ## CWE-327

CWE-327

    data = "Holy cow this is really bad"
    key = "NSA just got in my pants"

    cipher = OpenSSL::Cipher.new("aes-128-ecb") #FAIL
    cipher.encrypt
    cipher.key = key
    enc = cipher.update(data) + cipher.final
    puts "#{enc.unpack("H*").first}"
    # NO IV FAIL
    decipher = OpenSSL::Cipher.new("aes-128-ecb") #FAIL
    decipher.decrypt
    decipher.key = key
    plain = decipher.update(enc) + cipher.final
    puts "#{plain}"
# Not Using a Random IV with CBC Mode ## CWE-329
# CBC ![](img/CBC_encryption.jpg) Source: Wikipedia

CWE-329

    data = "Holy cow this is really bad"
    key = 'NSA just got in my pants'
    cipher = OpenSSL::Cipher.new("aes-128-cbc")
    cipher.encrypt
    cipher.key = key
    cipher.iv = key #FAIL
    enc = cipher.update(data) + cipher.final
    
    decipher = OpenSSL::Cipher.new("aes-128-cbc")
    decipher.decrypt
    decipher.key = key
    decipher.iv = key #FAIL
    plain = decipher.update(enc) + cipher.final
    puts "#{plain}"
# CBC ![](img/CBC_encryption_notes.jpg) Source: Wikipedia
# IVs must be # non # deterministic

CWE-329

    data = "NSA just got in my pants"
    cipher = OpenSSL::Cipher.new("aes-128-cbc")
    key = cipher.random_key
    iv = cipher.random_iv
    cipher.encrypt
    cipher.key = key
    cipher.iv = iv 
    enc = cipher.update(data) + cipher.final

    decipher = OpenSSL::Cipher.new("aes-128-cbc")
    decipher.decrypt
    decipher.key = key
    decipher.iv = iv
    plain = decipher.update(enc) + cipher.final
    puts "#{plain}"
# Weak crypto # primitives * MD4 * MD5 * ECB (already mentioned) * DES * 3DES or TripleDES
# Picking the right cipher # is hard
# Picking the right cipher mode # is hard
# Picking the # correct key size # is hard
# OpenSSL # portability # is hard
# Databases # are hard
# Threads # are hard
![](img/make_it_stop.jpg)
# We don't have the whole life # To play with # security
# It was supposed # to be simple
# We need # security # by default
# At the same time # full control for experts ## and legacys systems

Krypt

The Republic of

Securidad & Cryptago

Will it replace

< my fav. crypto library >

# Krypt makes use of # existing crypto libraries
# Coexists # peacefully
# Digest

Krypt


    require 'krypt'

    digest = Krypt::Digest::SHA256.new
    data = "NSA just got in my pants"

    puts digest.hexdigest(data)

OpenSSL


    require 'krypt'
    require 'krypt/provider/openssl'

    data = "NSA just got in my pants"

    ossl = Krypt::Provider::OpenSSL.new
    Krypt::Provider.register(ossl)

    digest = Krypt::Digest::SHA1.new
    puts digest.hexdigest(data)
# PBKDF2

Krypt


    require 'krypt'

    password = "strong"
    digest = Krypt::Digest::SHA256.new
    pbkdf2 = Krypt::PBKDF2.new(digest)

    salt = OpenSSL::Random.random_bytes(16)
    len = digest.digest_length
    iter = 20000

    hash = pbkdf2.generate_hex(password, salt, iter, len)
    puts "#{hash}"
# Already # at JRuby ![](img/jruby.jpg)

OpenSSL

    require 'krypt/provider/openssl'
    password = "strong"

    ossl = Krypt::Provider::OpenSSL.new
    Krypt::Provider.register(ossl)
    digest = Krypt::Digest::SHA256.new
    pbkdf2 = Krypt::PBKDF2.new(digest)

    salt = OpenSSL::Random.random_bytes(16)
    len = digest.digest_length
    iter = 20000

    hash = pbkdf2.generate_hex(password, salt, iter, len)
    puts "#{hash}"
# What about new providers?
![](img/libsodium.png)

Your own provider

    class RbNaCl
      def new_service(clazz, *args)
        if clazz == Krypt::Digest
          Digest.new
        else
          nil
        end
      end
    end

Keeping the same interface


    class Digest 
      %w(SHA256 SHA512).each do |alg|
        mod = Module.new do
          define_singleton_method(:new) { Digest.new(alg) }
        end
        const_set(alg, mod)
      end

      def initialize(alg)
        @@alg = alg.downcase
      end

      def hexdigest(data=nil)
        Crypto::Hash.send(@@alg, data, :hex)
      end
    end

Using your provider

    require 'krypt'
    require 'rbnacl-provider'

    data = "NSA just got in my pants"
    rbnacl = Example::Provider::RbNaCl.new

    Krypt::Provider.register(rbnacl)
    sha = Example::Digest::SHA256.new
    puts "SHA-256: #{sha.hexdigest(data)}"

What's next?

Finish cipher mode support

Incorporate AES, GCM

Replace Ruby's OpenSSL

# Community * `#kryptdev` on irc.freenode.net * [https://github.com/krypt/](https://github.com/krypt/) * Meet `@_emboss_` on twitter
# Thanks * [http://github.com/abstractj](http://github.com/abstractj) * [http://github.com/abstractj/krypt-examples](http://github.com/abstractj/krypt-examples)
## @abstractj