SlideShare a Scribd company logo
Information Security
Programming in Ruby
@nahi
@nahi - Twitter, Github
Software Engineer at https://www.treasuredata.com
OSS developer and enthusiast;
committer of CRuby and JRuby
Information Security Specialist
Information Security
Programming in Ruby
scripts:
https://github.com/nahi/ruby-crypt/tree/master/odrk05
References
JUS 2003 “PKI入門 - Ruby/OpenSSLを触りながら学ぶPKI”
https://github.com/nahi/ruby-crypt/raw/master/jus-pki.ppt
RubyKaigi 2006 “セキュアアプリケーションプログラミング”
https://github.com/nahi/ruby-
crypt/blob/master/rubykaigi2006/RubyKaigi2006_SAP_20060610.pdf
RubyConf 2012 “Ruby HTTP clients comparison”
http://www.slideshare.net/HiroshiNakamura/rubyhttp-clients-comparison
Information Security Programming
Confidentially
Authentication
Integrity
(Availability)
(Privacy)
(D) S for external C
[F] Encryption in S
[G] Encryption in C
[E] authentication
(C) S for internal C
(B) C for external S
7 Implementation Patterns
(A) C for internal S
(A)
(A)
(B)
(B)
(C)
(D)
[F]
[G]
[E]
[E]
Orange: Implementation target
Gray: External system
(D) S for external C
[F] Encryption in S
[G] Encryption in C
[E] authentication
(C) S for internal C
(B) C for external S
7 Implementation Patterns
(A) C for internal S
(A)
(A)
(B)
(B)
(C)
(D)
[F]
[G]
[E]
[E]
Orange: Implementation target
Gray: External system
… in Ruby
(A) C for internal S
(B) C for external S
(C) S for internal C
(D) S for external C
[E] authentication
[F] Encryption in S
[G] Encryption in C
(A)
(A)
(B)
(B)
(C)
[E]
[F]
[G]
(D)
[E]
Blue: Acceptable
Orange: Pitfalls
Red: No way
Protected communication
Fixed server authentication
➔ SSL configuration:
CBC, SSLv3.0, compression,
TLSv1.0, RC4, DHE1024, …
➔ Fails for wrong endpoint
(A) C for internal S
(A)
(A)
SSL configuration
require 'httpclient'
client = HTTPClient.new
client.get('https://www.ruby-lang.org/en/').status
% ruby a1.rb
ok: "/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA"
ok: "/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Domain Validation CA -
SHA256 - G2"
ok: "/OU=Domain Control Validated/CN=*.ruby-lang.org"
Protocol version: TLSv1.2
Cipher: ["ECDHE-RSA-AES128-GCM-SHA256", "TLSv1/SSLv3", 128, 128]
State: SSLOK : SSL negotiation finished successfully
Fails for wrong endpoint
require 'httpclient'
client = HTTPClient.new
client.get('https://hyogo-9327.herokussl.com/en/').status
% ruby -d a2.rb
ok: "/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA"
ok: "/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Domain Validation CA -
SHA256 - G2"
ok: "/OU=Domain Control Validated/CN=*.ruby-lang.org"
Protocol version: TLSv1.2
Cipher: ["ECDHE-RSA-AES128-GCM-SHA256", "TLSv1/SSLv3", 128, 128]
State: SSLOK : SSL negotiation finished successfully
Exception `OpenSSL::SSL::SSLError' - hostname "hyogo-9327.
herokussl.com" does not match the server certificate
require 'aws-sdk'
class KMSEncryptor
CTX = { 'purpose' => 'odrk05 demonstration' }
GCM_IV_SIZE = 12; GCM_TAG_SIZE = 16
def initialize(region, key_id)
@region, @key_id = region, key_id
@kms = Aws::KMS::Client.new(region: @region)
end
def generate_data_key
resp = @kms.generate_data_key_without_plaintext(
key_id: @key_id, encryption_context: CTX, key_spec: 'AES_128'
)
resp.ciphertext_blob
end
def with_key(wrapped_key)
key = nil
begin
key = @kms.decrypt(
ciphertext_blob: wrapped_key, encryption_context: CTX
).plaintext
yield key
ensure
# TODO: confirm that key is deleted from memory
key.tr!("0-xff".force_encoding('BINARY'), "0")
end
end
Fails for weak connection
require 'httpclient'
client = HTTPClient.new
client.ssl_config.ssl_version = :TLSv1_2
client.get('https://localhost:17443/').status
=begin
% ruby a3.rb
SSL_connect returned=1 errno=0 state=SSLv3 read server hello A:
wrong version number (OpenSSL::SSL::SSLError)
=end
Net::HTTP sample
require 'net/https'
class NetHTTPClient < Net::HTTP
require 'httpclient'
def do_start
if $DEBUG && @use_ssl
self.verify_callback = HTTPClient::SSLConfig.new(nil).
method(:default_verify_callback)
end
super
end
def on_connect
if $DEBUG && @use_ssl
ssl_socket = @socket.io
if ssl_socket.respond_to?(:ssl_version)
warn("Protocol version: #{ssl_socket.ssl_version}")
end
warn("Cipher: #{ssl_socket.cipher.inspect}")
warn("State: #{ssl_socket.state}")
end
super
end
end
# =>
# =>
client = NetHTTPClient.new(
"www.ruby-lang.org", 443)
client.use_ssl = true
client.cert_store =
store = OpenSSL::X509::Store.new
store.set_default_paths
client.get("/")
Protected communication
Restricted server authentication
➔ SSL configuration
➔ Fails for revoked server
(B) C for external S
(A)
(A)
(B)
(B)
Revocation check
require 'httpclient' # >= 2.7.0
client = HTTPClient.new
client.get('https://test-sspev.verisign.com:2443/test-SSPEV-
revoked-verisign.html').status
% ruby b.rb # => 200
% jruby b.rb # => 200
% jruby -J-Dcom.sun.security.enableCRLDP=true 
-J-Dcom.sun.net.ssl.checkRevocation=true b.rb
OpenSSL::SSL::SSLError:
sun.security.validator.ValidatorException: PKIX path validation
failed: java.security.cert.CertPathValidatorException: Certificate
has been revoked, reason: UNSPECIFIED, revocation date: Thu Oct 30
06:29:37 JST 2014, authority: CN=Symantec Class 3 EV SSL CA - G3,
OU=Symantec Trust Network, O=Symantec Corporation, C=US
OpenSSL...?
Protected communication
Restricted client authentication
➔ SSL configuration
➔ Server key management
➔ Certificate rotation
➔ Fails for unexpected clients
(C) S for internal C
(C)
WEBrick SSL server
require 'webrick/https'
require 'logger'
logger = Logger.new(STDERR)
server = WEBrick::HTTPServer.new(
BindAddress: "localhost",
Logger: logger,
Port: 17443,
DocumentRoot: '/dev/null',
SSLEnable: true,
SSLCACertificateFile: 'ca-chain.cert',
SSLCertificate:
OpenSSL::X509::Certificate.new(
File.read('server.cert')),
SSLPrivateKey: OpenSSL::PKey::RSA.new(
File.read('server.key')),
)
basic_auth=WEBrick::HTTPAuth::BasicAuth.new(
Logger: logger,
Realm: 'auth',
UserDB: WEBrick::HTTPAuth::Htpasswd.new(
'htpasswd')
)
# =>
# =>
server.mount('/hello',
WEBrick::HTTPServlet::ProcHandler.new(
->(req, res) {
basic_auth.authenticate(req, res)
res['content-type'] = 'text/plain'
res.body = 'hello'
})
)
trap(:INT) do
server.shutdown
end
t = Thread.new {
Thread.current.abort_on_exception =
true
server.start
}
while server.status != :Running
sleep 0.1
raise unless t.alive?
end
puts $$
t.join
Protected communication
Client authentication
➔ SSL configuration
➔ Server key management
➔ Certificate rotation
➔ Fails for unexpected clients
➔ Recovery from key compromise
You have better solutions (Apache, Nginx, ELB, …)
(D) S for external C
(C)
(D)
Client authentication
On unprotected network
➔ Cipher algorithm
➔ Tamper detection
➔ Constant time operation
Use well-known library
[E] authentication
[E]
[E]
Data protection at rest
➔ Cipher algorithm
➔ Encryption key management
◆ Storage
◆ Usage authn / authz
◆ Usage auditing
◆ Rotation
➔ Tamper detection
➔ Processing throughput / latency
[F] Encryption in S / [G] in C
[F]
[G]
require 'aws-sdk'
class KMSEncryptor
CTX = { 'purpose' => 'odrk05 demonstration' }
GCM_IV_SIZE = 12; GCM_TAG_SIZE = 16
def initialize(region, key_id)
@region, @key_id = region, key_id
@kms = Aws::KMS::Client.new(region: @region)
end
def generate_data_key
resp = @kms.generate_data_key_without_plaintext(
key_id: @key_id, encryption_context: CTX, key_spec: 'AES_128'
)
resp.ciphertext_blob
end
def with_key(wrapped_key)
key = nil
begin
key = @kms.decrypt(
ciphertext_blob: wrapped_key, encryption_context: CTX
).plaintext
yield key
ensure
# TODO: confirm that key is deleted from memory
key.tr!("0-xff".force_encoding('BINARY'), "0")
end
end
def encrypt(wrapped_key, plaintext)
with_key(wrapped_key) do |key|
cipher = OpenSSL::Cipher::Cipher.new('aes-128-gcm')
iv = OpenSSL::Random.random_bytes(GCM_IV_SIZE)
cipher.encrypt; cipher.key = key;cipher.iv = iv
iv + cipher.update(plaintext) + cipher.final
end
end
def decrypt(wrapped_key, ciphertext)
with_key(wrapped_key) do |key|
iv, data = ciphertext.unpack("a#{GCM_IV_SIZE}a*")
auth_tag = data.slice!(data.bytesize - GCM_TAG_SIZE, GCM_TAG_SIZE)
cipher = OpenSSL::Cipher::Cipher.new('aes-128-gcm')
cipher.decrypt; cipher.key = key; cipher.iv = iv
cipher.auth_tag = auth_tag
cipher.update(data) + cipher.final
end
end
end
encryptor = KMSEncryptor.new('ap-northeast-1', 'alias/nahi-test-tokyo')
# generate key for each data, customer, or something
wrapped_key = encryptor.generate_data_key
plaintext = File.read(__FILE__)
ciphertext = encryptor.encrypt(wrapped_key, plaintext)
# save wrapped_key and ciphertext in DB, File or somewhere
# restore wrapped_key and ciphertext from DB, File or somewhere
puts encryptor.decrypt(wrapped_key, ciphertext)
jruby-openssl does not
support aes-gcm…
-> next page
if defined?(JRuby)
require 'java'
java_import 'javax.crypto.Cipher'
java_import 'javax.crypto.SecretKey'
java_import 'javax.crypto.spec.SecretKeySpec'
java_import 'javax.crypto.spec.GCMParameterSpec'
class KMSEncryptor
# Overrides
def encrypt(wrapped_key, plaintext)
with_key(wrapped_key) do |key|
cipher = Cipher.getInstance('AES/GCM/PKCS5Padding')
iv = OpenSSL::Random.random_bytes(GCM_IV_SIZE)
spec = GCMParameterSpec.new(GCM_TAG_SIZE * 8, iv.to_java_bytes)
cipher.init(1, SecretKeySpec.new(key.to_java_bytes, 0, key.bytesize, 'AES'), spec)
ciphertext = String.from_java_bytes(
cipher.doFinal(plaintext.to_java_bytes), Encoding::BINARY)
iv + ciphertext
end
end
# Overrides
def decrypt(wrapped_key, ciphertext)
with_key(wrapped_key) do |key|
cipher = Cipher.getInstance('AES/GCM/PKCS5Padding')
iv, data = ciphertext.unpack("a#{GCM_IV_SIZE}a*")
spec = GCMParameterSpec.new(GCM_TAG_SIZE * 8, iv.to_java_bytes)
cipher.init(2, SecretKeySpec.new(key.to_java_bytes, 0, key.bytesize, 'AES'), spec)
String.from_java_bytes(cipher.doFinal(data.to_java_bytes), Encoding::BINARY)
end
end
end
end
aes-128-gcm in JRuby!
… in Ruby
(A) C for internal S
(B) C for external S
(C) S for internal C
(D) S for external C
[E] authentication
[F] Encryption in S
[G] Encryption in C
(A)
(A)
(B)
(B)
(C)
[E]
[F]
[G]
(D)
[E]
Blue: Acceptable
Orange: Pitfalls
Red: No way

More Related Content

What's hot (20)

Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
Hiroshi SHIBATA
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
Mark Baker
 
Roll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and LuaRoll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and Lua
Jon Moore
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service Manager
Chris Tankersley
 
Lua tech talk
Lua tech talkLua tech talk
Lua tech talk
Locaweb
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
Gabriele Lana
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
Bram Vogelaar
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
Gleicon Moraes
 
Submit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло МорозовSubmit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло Морозов
Binary Studio
 
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf Conference
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
Tatsuhiko Miyagawa
 
Introduction to Flask Micro Framework
Introduction to Flask Micro FrameworkIntroduction to Flask Micro Framework
Introduction to Flask Micro Framework
Mohammad Reza Kamalifard
 
Using ngx_lua in UPYUN
Using ngx_lua in UPYUNUsing ngx_lua in UPYUN
Using ngx_lua in UPYUN
Cong Zhang
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
Alena Holligan
 
Little Big Ruby
Little Big RubyLittle Big Ruby
Little Big Ruby
LittleBIGRuby
 
Node.js streaming csv downloads proxy
Node.js streaming csv downloads proxyNode.js streaming csv downloads proxy
Node.js streaming csv downloads proxy
Ismael Celis
 
The Parenscript Common Lisp to JavaScript compiler
The Parenscript Common Lisp to JavaScript compilerThe Parenscript Common Lisp to JavaScript compiler
The Parenscript Common Lisp to JavaScript compiler
Vladimir Sedach
 
Pycon - Python for ethical hackers
Pycon - Python for ethical hackers Pycon - Python for ethical hackers
Pycon - Python for ethical hackers
Mohammad Reza Kamalifard
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
charsbar
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
Tatsuhiko Miyagawa
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
Hiroshi SHIBATA
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
Mark Baker
 
Roll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and LuaRoll Your Own API Management Platform with nginx and Lua
Roll Your Own API Management Platform with nginx and Lua
Jon Moore
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service Manager
Chris Tankersley
 
Lua tech talk
Lua tech talkLua tech talk
Lua tech talk
Locaweb
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
Bram Vogelaar
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
Gleicon Moraes
 
Submit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло МорозовSubmit PHP: Standards in PHP world. Михайло Морозов
Submit PHP: Standards in PHP world. Михайло Морозов
Binary Studio
 
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf Conference
 
Using ngx_lua in UPYUN
Using ngx_lua in UPYUNUsing ngx_lua in UPYUN
Using ngx_lua in UPYUN
Cong Zhang
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
Alena Holligan
 
Node.js streaming csv downloads proxy
Node.js streaming csv downloads proxyNode.js streaming csv downloads proxy
Node.js streaming csv downloads proxy
Ismael Celis
 
The Parenscript Common Lisp to JavaScript compiler
The Parenscript Common Lisp to JavaScript compilerThe Parenscript Common Lisp to JavaScript compiler
The Parenscript Common Lisp to JavaScript compiler
Vladimir Sedach
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
charsbar
 

Similar to Information security programming in ruby (20)

VisualWorks Security Reloaded - STIC 2012
VisualWorks Security Reloaded - STIC 2012VisualWorks Security Reloaded - STIC 2012
VisualWorks Security Reloaded - STIC 2012
Martin Kobetic
 
5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...
Alexander Decker
 
5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...
Alexander Decker
 
Transport Layer Security
Transport Layer SecurityTransport Layer Security
Transport Layer Security
n|u - The Open Security Community
 
Transport Layer Security - Mrinal Wadhwa
Transport Layer Security - Mrinal WadhwaTransport Layer Security - Mrinal Wadhwa
Transport Layer Security - Mrinal Wadhwa
Mrinal Wadhwa
 
TLS/SSL Protocol Design 201006
TLS/SSL Protocol Design 201006TLS/SSL Protocol Design 201006
TLS/SSL Protocol Design 201006
Nate Lawson
 
SSL/TLS
SSL/TLSSSL/TLS
SSL/TLS
pavansmiles
 
Django cryptography
Django cryptographyDjango cryptography
Django cryptography
Erik LaBianca
 
Secure Communications with VisualWorks - CSTUC 2006
Secure Communications with VisualWorks - CSTUC 2006Secure Communications with VisualWorks - CSTUC 2006
Secure Communications with VisualWorks - CSTUC 2006
Martin Kobetic
 
TLS/SSL Protocol Design
TLS/SSL Protocol DesignTLS/SSL Protocol Design
TLS/SSL Protocol Design
Nate Lawson
 
21 05-2018
21 05-201821 05-2018
21 05-2018
Praaveen Vr
 
crypto2ssh
crypto2sshcrypto2ssh
crypto2ssh
Hasan Sharif
 
Part2-Apps-Security.pptx
Part2-Apps-Security.pptxPart2-Apps-Security.pptx
Part2-Apps-Security.pptx
Olivier Bonaventure
 
Cryptography (under)engineering
Cryptography (under)engineeringCryptography (under)engineering
Cryptography (under)engineering
slicklash
 
Atonomy of-a-tls-handshake-mini-conferentie
Atonomy of-a-tls-handshake-mini-conferentieAtonomy of-a-tls-handshake-mini-conferentie
Atonomy of-a-tls-handshake-mini-conferentie
Michel Schudel
 
Ruby で覚える TOTP
Ruby で覚える TOTPRuby で覚える TOTP
Ruby で覚える TOTP
Daichi Hioki
 
Network security
Network securityNetwork security
Network security
anoop negi
 
SSL intro
SSL introSSL intro
SSL intro
Three Lee
 
SSL Primer
SSL PrimerSSL Primer
SSL Primer
Mahadev Gaonkar
 
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
BookNet Canada
 
VisualWorks Security Reloaded - STIC 2012
VisualWorks Security Reloaded - STIC 2012VisualWorks Security Reloaded - STIC 2012
VisualWorks Security Reloaded - STIC 2012
Martin Kobetic
 
5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...
Alexander Decker
 
5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...5.[29 38]a practical approach for implementation of public key infrastructure...
5.[29 38]a practical approach for implementation of public key infrastructure...
Alexander Decker
 
Transport Layer Security - Mrinal Wadhwa
Transport Layer Security - Mrinal WadhwaTransport Layer Security - Mrinal Wadhwa
Transport Layer Security - Mrinal Wadhwa
Mrinal Wadhwa
 
TLS/SSL Protocol Design 201006
TLS/SSL Protocol Design 201006TLS/SSL Protocol Design 201006
TLS/SSL Protocol Design 201006
Nate Lawson
 
Secure Communications with VisualWorks - CSTUC 2006
Secure Communications with VisualWorks - CSTUC 2006Secure Communications with VisualWorks - CSTUC 2006
Secure Communications with VisualWorks - CSTUC 2006
Martin Kobetic
 
TLS/SSL Protocol Design
TLS/SSL Protocol DesignTLS/SSL Protocol Design
TLS/SSL Protocol Design
Nate Lawson
 
Cryptography (under)engineering
Cryptography (under)engineeringCryptography (under)engineering
Cryptography (under)engineering
slicklash
 
Atonomy of-a-tls-handshake-mini-conferentie
Atonomy of-a-tls-handshake-mini-conferentieAtonomy of-a-tls-handshake-mini-conferentie
Atonomy of-a-tls-handshake-mini-conferentie
Michel Schudel
 
Ruby で覚える TOTP
Ruby で覚える TOTPRuby で覚える TOTP
Ruby で覚える TOTP
Daichi Hioki
 
Network security
Network securityNetwork security
Network security
anoop negi
 
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
BookNet Canada
 
Ad

More from Hiroshi Nakamura (9)

エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSS
Hiroshi Nakamura
 
Embulk 20150411
Embulk 20150411Embulk 20150411
Embulk 20150411
Hiroshi Nakamura
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvas
Hiroshi Nakamura
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
Hiroshi Nakamura
 
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyJavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
Hiroshi Nakamura
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)
Hiroshi Nakamura
 
現実世界のJRuby
現実世界のJRuby現実世界のJRuby
現実世界のJRuby
Hiroshi Nakamura
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方
Hiroshi Nakamura
 
HSM超入門講座
HSM超入門講座HSM超入門講座
HSM超入門講座
Hiroshi Nakamura
 
エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSS
Hiroshi Nakamura
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvas
Hiroshi Nakamura
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
Hiroshi Nakamura
 
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyJavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
Hiroshi Nakamura
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)
Hiroshi Nakamura
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方
Hiroshi Nakamura
 
Ad

Recently uploaded (20)

Rebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core FoundationRebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core Foundation
Cadabra Studio
 
IBM Rational Unified Process For Software Engineering - Introduction
IBM Rational Unified Process For Software Engineering - IntroductionIBM Rational Unified Process For Software Engineering - Introduction
IBM Rational Unified Process For Software Engineering - Introduction
Gaurav Sharma
 
Agentic Techniques in Retrieval-Augmented Generation with Azure AI Search
Agentic Techniques in Retrieval-Augmented Generation with Azure AI SearchAgentic Techniques in Retrieval-Augmented Generation with Azure AI Search
Agentic Techniques in Retrieval-Augmented Generation with Azure AI Search
Maxim Salnikov
 
14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework
Angelo Theodorou
 
The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...
Prachi Desai
 
Revolutionize Your Insurance Workflow with Claims Management Software
Revolutionize Your Insurance Workflow with Claims Management SoftwareRevolutionize Your Insurance Workflow with Claims Management Software
Revolutionize Your Insurance Workflow with Claims Management Software
Insurance Tech Services
 
Generative Artificial Intelligence and its Applications
Generative Artificial Intelligence and its ApplicationsGenerative Artificial Intelligence and its Applications
Generative Artificial Intelligence and its Applications
SandeepKS52
 
Leveraging Foundation Models to Infer Intents
Leveraging Foundation Models to Infer IntentsLeveraging Foundation Models to Infer Intents
Leveraging Foundation Models to Infer Intents
Keheliya Gallaba
 
iOS Developer Resume 2025 | Pramod Kumar
iOS Developer Resume 2025 | Pramod KumariOS Developer Resume 2025 | Pramod Kumar
iOS Developer Resume 2025 | Pramod Kumar
Pramod Kumar
 
Best Inbound Call Tracking Software for Small Businesses
Best Inbound Call Tracking Software for Small BusinessesBest Inbound Call Tracking Software for Small Businesses
Best Inbound Call Tracking Software for Small Businesses
TheTelephony
 
zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17
zOSCommserver
 
Simplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for ContractorsSimplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for Contractors
SHEQ Network Limited
 
Neuralink Templateeeeeeeeeeeeeeeeeeeeeeeeee
Neuralink TemplateeeeeeeeeeeeeeeeeeeeeeeeeeNeuralink Templateeeeeeeeeeeeeeeeeeeeeeeeee
Neuralink Templateeeeeeeeeeeeeeeeeeeeeeeeee
alexandernoetzold
 
Bonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdfBonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdf
Herond Labs
 
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptxHow AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
kalichargn70th171
 
FME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable InsightsFME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable Insights
Safe Software
 
Design by Contract - Building Robust Software with Contract-First Development
Design by Contract - Building Robust Software with Contract-First DevelopmentDesign by Contract - Building Robust Software with Contract-First Development
Design by Contract - Building Robust Software with Contract-First Development
Par-Tec S.p.A.
 
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The SequelMarketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
BradBedford3
 
How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...
How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...
How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...
Insurance Tech Services
 
Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3
Gaurav Sharma
 
Rebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core FoundationRebuilding Cadabra Studio: AI as Our Core Foundation
Rebuilding Cadabra Studio: AI as Our Core Foundation
Cadabra Studio
 
IBM Rational Unified Process For Software Engineering - Introduction
IBM Rational Unified Process For Software Engineering - IntroductionIBM Rational Unified Process For Software Engineering - Introduction
IBM Rational Unified Process For Software Engineering - Introduction
Gaurav Sharma
 
Agentic Techniques in Retrieval-Augmented Generation with Azure AI Search
Agentic Techniques in Retrieval-Augmented Generation with Azure AI SearchAgentic Techniques in Retrieval-Augmented Generation with Azure AI Search
Agentic Techniques in Retrieval-Augmented Generation with Azure AI Search
Maxim Salnikov
 
14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework
Angelo Theodorou
 
The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...
Prachi Desai
 
Revolutionize Your Insurance Workflow with Claims Management Software
Revolutionize Your Insurance Workflow with Claims Management SoftwareRevolutionize Your Insurance Workflow with Claims Management Software
Revolutionize Your Insurance Workflow with Claims Management Software
Insurance Tech Services
 
Generative Artificial Intelligence and its Applications
Generative Artificial Intelligence and its ApplicationsGenerative Artificial Intelligence and its Applications
Generative Artificial Intelligence and its Applications
SandeepKS52
 
Leveraging Foundation Models to Infer Intents
Leveraging Foundation Models to Infer IntentsLeveraging Foundation Models to Infer Intents
Leveraging Foundation Models to Infer Intents
Keheliya Gallaba
 
iOS Developer Resume 2025 | Pramod Kumar
iOS Developer Resume 2025 | Pramod KumariOS Developer Resume 2025 | Pramod Kumar
iOS Developer Resume 2025 | Pramod Kumar
Pramod Kumar
 
Best Inbound Call Tracking Software for Small Businesses
Best Inbound Call Tracking Software for Small BusinessesBest Inbound Call Tracking Software for Small Businesses
Best Inbound Call Tracking Software for Small Businesses
TheTelephony
 
zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17
zOSCommserver
 
Simplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for ContractorsSimplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for Contractors
SHEQ Network Limited
 
Neuralink Templateeeeeeeeeeeeeeeeeeeeeeeeee
Neuralink TemplateeeeeeeeeeeeeeeeeeeeeeeeeeNeuralink Templateeeeeeeeeeeeeeeeeeeeeeeeee
Neuralink Templateeeeeeeeeeeeeeeeeeeeeeeeee
alexandernoetzold
 
Bonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdfBonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdf
Herond Labs
 
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptxHow AI Can Improve Media Quality Testing Across Platforms (1).pptx
How AI Can Improve Media Quality Testing Across Platforms (1).pptx
kalichargn70th171
 
FME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable InsightsFME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable Insights
Safe Software
 
Design by Contract - Building Robust Software with Contract-First Development
Design by Contract - Building Robust Software with Contract-First DevelopmentDesign by Contract - Building Robust Software with Contract-First Development
Design by Contract - Building Robust Software with Contract-First Development
Par-Tec S.p.A.
 
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The SequelMarketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
BradBedford3
 
How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...
How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...
How Insurance Policy Administration Streamlines Policy Lifecycle for Agile Op...
Insurance Tech Services
 
Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3
Gaurav Sharma
 

Information security programming in ruby

  • 2. @nahi - Twitter, Github Software Engineer at https://www.treasuredata.com OSS developer and enthusiast; committer of CRuby and JRuby Information Security Specialist
  • 3. Information Security Programming in Ruby scripts: https://github.com/nahi/ruby-crypt/tree/master/odrk05
  • 4. References JUS 2003 “PKI入門 - Ruby/OpenSSLを触りながら学ぶPKI” https://github.com/nahi/ruby-crypt/raw/master/jus-pki.ppt RubyKaigi 2006 “セキュアアプリケーションプログラミング” https://github.com/nahi/ruby- crypt/blob/master/rubykaigi2006/RubyKaigi2006_SAP_20060610.pdf RubyConf 2012 “Ruby HTTP clients comparison” http://www.slideshare.net/HiroshiNakamura/rubyhttp-clients-comparison
  • 6. (D) S for external C [F] Encryption in S [G] Encryption in C [E] authentication (C) S for internal C (B) C for external S 7 Implementation Patterns (A) C for internal S (A) (A) (B) (B) (C) (D) [F] [G] [E] [E] Orange: Implementation target Gray: External system
  • 7. (D) S for external C [F] Encryption in S [G] Encryption in C [E] authentication (C) S for internal C (B) C for external S 7 Implementation Patterns (A) C for internal S (A) (A) (B) (B) (C) (D) [F] [G] [E] [E] Orange: Implementation target Gray: External system
  • 8. … in Ruby (A) C for internal S (B) C for external S (C) S for internal C (D) S for external C [E] authentication [F] Encryption in S [G] Encryption in C (A) (A) (B) (B) (C) [E] [F] [G] (D) [E] Blue: Acceptable Orange: Pitfalls Red: No way
  • 9. Protected communication Fixed server authentication ➔ SSL configuration: CBC, SSLv3.0, compression, TLSv1.0, RC4, DHE1024, … ➔ Fails for wrong endpoint (A) C for internal S (A) (A)
  • 10. SSL configuration require 'httpclient' client = HTTPClient.new client.get('https://www.ruby-lang.org/en/').status % ruby a1.rb ok: "/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA" ok: "/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Domain Validation CA - SHA256 - G2" ok: "/OU=Domain Control Validated/CN=*.ruby-lang.org" Protocol version: TLSv1.2 Cipher: ["ECDHE-RSA-AES128-GCM-SHA256", "TLSv1/SSLv3", 128, 128] State: SSLOK : SSL negotiation finished successfully
  • 11. Fails for wrong endpoint require 'httpclient' client = HTTPClient.new client.get('https://hyogo-9327.herokussl.com/en/').status % ruby -d a2.rb ok: "/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA" ok: "/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Domain Validation CA - SHA256 - G2" ok: "/OU=Domain Control Validated/CN=*.ruby-lang.org" Protocol version: TLSv1.2 Cipher: ["ECDHE-RSA-AES128-GCM-SHA256", "TLSv1/SSLv3", 128, 128] State: SSLOK : SSL negotiation finished successfully Exception `OpenSSL::SSL::SSLError' - hostname "hyogo-9327. herokussl.com" does not match the server certificate
  • 12. require 'aws-sdk' class KMSEncryptor CTX = { 'purpose' => 'odrk05 demonstration' } GCM_IV_SIZE = 12; GCM_TAG_SIZE = 16 def initialize(region, key_id) @region, @key_id = region, key_id @kms = Aws::KMS::Client.new(region: @region) end def generate_data_key resp = @kms.generate_data_key_without_plaintext( key_id: @key_id, encryption_context: CTX, key_spec: 'AES_128' ) resp.ciphertext_blob end def with_key(wrapped_key) key = nil begin key = @kms.decrypt( ciphertext_blob: wrapped_key, encryption_context: CTX ).plaintext yield key ensure # TODO: confirm that key is deleted from memory key.tr!("0-xff".force_encoding('BINARY'), "0") end end
  • 13. Fails for weak connection require 'httpclient' client = HTTPClient.new client.ssl_config.ssl_version = :TLSv1_2 client.get('https://localhost:17443/').status =begin % ruby a3.rb SSL_connect returned=1 errno=0 state=SSLv3 read server hello A: wrong version number (OpenSSL::SSL::SSLError) =end
  • 14. Net::HTTP sample require 'net/https' class NetHTTPClient < Net::HTTP require 'httpclient' def do_start if $DEBUG && @use_ssl self.verify_callback = HTTPClient::SSLConfig.new(nil). method(:default_verify_callback) end super end def on_connect if $DEBUG && @use_ssl ssl_socket = @socket.io if ssl_socket.respond_to?(:ssl_version) warn("Protocol version: #{ssl_socket.ssl_version}") end warn("Cipher: #{ssl_socket.cipher.inspect}") warn("State: #{ssl_socket.state}") end super end end # => # => client = NetHTTPClient.new( "www.ruby-lang.org", 443) client.use_ssl = true client.cert_store = store = OpenSSL::X509::Store.new store.set_default_paths client.get("/")
  • 15. Protected communication Restricted server authentication ➔ SSL configuration ➔ Fails for revoked server (B) C for external S (A) (A) (B) (B)
  • 16. Revocation check require 'httpclient' # >= 2.7.0 client = HTTPClient.new client.get('https://test-sspev.verisign.com:2443/test-SSPEV- revoked-verisign.html').status % ruby b.rb # => 200 % jruby b.rb # => 200 % jruby -J-Dcom.sun.security.enableCRLDP=true -J-Dcom.sun.net.ssl.checkRevocation=true b.rb OpenSSL::SSL::SSLError: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Certificate has been revoked, reason: UNSPECIFIED, revocation date: Thu Oct 30 06:29:37 JST 2014, authority: CN=Symantec Class 3 EV SSL CA - G3, OU=Symantec Trust Network, O=Symantec Corporation, C=US OpenSSL...?
  • 17. Protected communication Restricted client authentication ➔ SSL configuration ➔ Server key management ➔ Certificate rotation ➔ Fails for unexpected clients (C) S for internal C (C)
  • 18. WEBrick SSL server require 'webrick/https' require 'logger' logger = Logger.new(STDERR) server = WEBrick::HTTPServer.new( BindAddress: "localhost", Logger: logger, Port: 17443, DocumentRoot: '/dev/null', SSLEnable: true, SSLCACertificateFile: 'ca-chain.cert', SSLCertificate: OpenSSL::X509::Certificate.new( File.read('server.cert')), SSLPrivateKey: OpenSSL::PKey::RSA.new( File.read('server.key')), ) basic_auth=WEBrick::HTTPAuth::BasicAuth.new( Logger: logger, Realm: 'auth', UserDB: WEBrick::HTTPAuth::Htpasswd.new( 'htpasswd') ) # => # => server.mount('/hello', WEBrick::HTTPServlet::ProcHandler.new( ->(req, res) { basic_auth.authenticate(req, res) res['content-type'] = 'text/plain' res.body = 'hello' }) ) trap(:INT) do server.shutdown end t = Thread.new { Thread.current.abort_on_exception = true server.start } while server.status != :Running sleep 0.1 raise unless t.alive? end puts $$ t.join
  • 19. Protected communication Client authentication ➔ SSL configuration ➔ Server key management ➔ Certificate rotation ➔ Fails for unexpected clients ➔ Recovery from key compromise You have better solutions (Apache, Nginx, ELB, …) (D) S for external C (C) (D)
  • 20. Client authentication On unprotected network ➔ Cipher algorithm ➔ Tamper detection ➔ Constant time operation Use well-known library [E] authentication [E] [E]
  • 21. Data protection at rest ➔ Cipher algorithm ➔ Encryption key management ◆ Storage ◆ Usage authn / authz ◆ Usage auditing ◆ Rotation ➔ Tamper detection ➔ Processing throughput / latency [F] Encryption in S / [G] in C [F] [G]
  • 22. require 'aws-sdk' class KMSEncryptor CTX = { 'purpose' => 'odrk05 demonstration' } GCM_IV_SIZE = 12; GCM_TAG_SIZE = 16 def initialize(region, key_id) @region, @key_id = region, key_id @kms = Aws::KMS::Client.new(region: @region) end def generate_data_key resp = @kms.generate_data_key_without_plaintext( key_id: @key_id, encryption_context: CTX, key_spec: 'AES_128' ) resp.ciphertext_blob end def with_key(wrapped_key) key = nil begin key = @kms.decrypt( ciphertext_blob: wrapped_key, encryption_context: CTX ).plaintext yield key ensure # TODO: confirm that key is deleted from memory key.tr!("0-xff".force_encoding('BINARY'), "0") end end
  • 23. def encrypt(wrapped_key, plaintext) with_key(wrapped_key) do |key| cipher = OpenSSL::Cipher::Cipher.new('aes-128-gcm') iv = OpenSSL::Random.random_bytes(GCM_IV_SIZE) cipher.encrypt; cipher.key = key;cipher.iv = iv iv + cipher.update(plaintext) + cipher.final end end def decrypt(wrapped_key, ciphertext) with_key(wrapped_key) do |key| iv, data = ciphertext.unpack("a#{GCM_IV_SIZE}a*") auth_tag = data.slice!(data.bytesize - GCM_TAG_SIZE, GCM_TAG_SIZE) cipher = OpenSSL::Cipher::Cipher.new('aes-128-gcm') cipher.decrypt; cipher.key = key; cipher.iv = iv cipher.auth_tag = auth_tag cipher.update(data) + cipher.final end end end encryptor = KMSEncryptor.new('ap-northeast-1', 'alias/nahi-test-tokyo') # generate key for each data, customer, or something wrapped_key = encryptor.generate_data_key plaintext = File.read(__FILE__) ciphertext = encryptor.encrypt(wrapped_key, plaintext) # save wrapped_key and ciphertext in DB, File or somewhere # restore wrapped_key and ciphertext from DB, File or somewhere puts encryptor.decrypt(wrapped_key, ciphertext) jruby-openssl does not support aes-gcm… -> next page
  • 24. if defined?(JRuby) require 'java' java_import 'javax.crypto.Cipher' java_import 'javax.crypto.SecretKey' java_import 'javax.crypto.spec.SecretKeySpec' java_import 'javax.crypto.spec.GCMParameterSpec' class KMSEncryptor # Overrides def encrypt(wrapped_key, plaintext) with_key(wrapped_key) do |key| cipher = Cipher.getInstance('AES/GCM/PKCS5Padding') iv = OpenSSL::Random.random_bytes(GCM_IV_SIZE) spec = GCMParameterSpec.new(GCM_TAG_SIZE * 8, iv.to_java_bytes) cipher.init(1, SecretKeySpec.new(key.to_java_bytes, 0, key.bytesize, 'AES'), spec) ciphertext = String.from_java_bytes( cipher.doFinal(plaintext.to_java_bytes), Encoding::BINARY) iv + ciphertext end end # Overrides def decrypt(wrapped_key, ciphertext) with_key(wrapped_key) do |key| cipher = Cipher.getInstance('AES/GCM/PKCS5Padding') iv, data = ciphertext.unpack("a#{GCM_IV_SIZE}a*") spec = GCMParameterSpec.new(GCM_TAG_SIZE * 8, iv.to_java_bytes) cipher.init(2, SecretKeySpec.new(key.to_java_bytes, 0, key.bytesize, 'AES'), spec) String.from_java_bytes(cipher.doFinal(data.to_java_bytes), Encoding::BINARY) end end end end aes-128-gcm in JRuby!
  • 25. … in Ruby (A) C for internal S (B) C for external S (C) S for internal C (D) S for external C [E] authentication [F] Encryption in S [G] Encryption in C (A) (A) (B) (B) (C) [E] [F] [G] (D) [E] Blue: Acceptable Orange: Pitfalls Red: No way