SlideShare una empresa de Scribd logo
1 de 74
Descargar para leer sin conexión
Whispered Secrets
Eleanor McHugh
Whispered Secrets
@feyeleanor
http://leanpub.com/GoNotebook
we all have secrets
and these secrets matter to us
that’s what makes them secrets
software should keep our secrets
some secrets are awful
conspiracy
infidelity
criminality
some secrets are banal
bank account numbers
embarrassing incidents
sexual preferences
secrecy should be absolute
our tech must protect the awful
or it won’t protect the banal
but there are laws
we must comply with these
assist the legitimate
deny the illegitimate
secrecy ——> privacy
privacy is not absolute
privacy requires mutual trust
mutual trust is a contract
and contracts can be broken
famous broken contracts
Ashley-Madison
Carphone Warehouse
Office of Personnel Management
today’s topic is applied paranoia
paranoia
Pronunciation: /ˌparəәˈnɔɪəә/
noun
{mass noun}
A mental condition characterized by delusions of persecution, unwarranted
jealousy, or exaggerated self-importance, typically worked into an organized
system. It may be an aspect of chronic personality disorder, of drug abuse, or
of a serious condition such as schizophrenia in which the person loses touch
with reality.
Unjustified suspicion and mistrust of other people:
mild paranoia afflicts all prime ministers
13
paranoia
Pronunciation: /ˌparəәˈnɔɪəә/
noun
{mass noun}
The perfectly reasonable belief that someone, somewhere is watching your
online behaviour with malicious and/or voyeuristic intent. It may be a result
of reading a Hacking Exposed or Hacking for Dummies publication,
experiencing the fallout from identity theft, or shopping with bitcoin.
Justified suspicion and mistrust of other people:
chronic paranoia afflicts all information security professionals
accute paranoia afflicts the victims of hacking
17
18
we have to trust governments
governments are privileged
if we don’t obey they can hurt us
not much we can do about that
19
20
our users have to trust us
our services are privileged
they store real-world secrets
and identifying metadata
21
but who can we trust?
technology bars the gates
but people create the bars
and people have to monitor them
22
so what do we do?
dev practices
architecture
operational rules
23
privacy ——> dev practices
whispered secrets http://slides.games-with-brains.net/25
whispered secrets http://slides.games-with-brains.net/26
privacy ——> architecture
encrypt all transports
• establish a secure channel by exchanging public keys
• and check their validity against trusted certificates (SSL, TLS, etc.)
• as an added measure pin these certificates (like SSH pins keys)
• then exchange symmetric keys for a private secure channel
• change these keys frequently (cheap cipher streams)
• and pin each distinct message to a distinct key (one-time pads)
28
https
29
package main
import . "fmt"
import . "net/http"
const ADDRESS = ":443"
func main() {
message := "hello world"
HandleFunc("/hello", func(w ResponseWriter, r *Request) {
w.Header().Set("Content-Type", "text/plain")
Fprintf(w, message)
})
ListenAndServeTLS(ADDRESS, "cert.pem", "key.pem", nil)
}
whispered secrets http://slides.games-with-brains.net/30
package main
import . "fmt"
import . "net/http"
const ADDRESS = ":443"
func main() {
message := "hello world"
HandleFunc("/hello", func(w ResponseWriter, r *Request) {
w.Header().Set("Content-Type", "text/plain")
Fprintf(w, message)
})
ListenAndServeTLS(ADDRESS, "cert.pem", "key.pem", nil)
}
whispered secrets http://slides.games-with-brains.net/31
package main
import . "fmt"
import . "net/http"
const ADDRESS = ":443"
func main() {
message := "hello world"
HandleFunc("/hello", func(w ResponseWriter, r *Request) {
w.Header().Set("Content-Type", "text/plain")
Fprintf(w, message)
})
ListenAndServeTLS(ADDRESS, "cert.pem", "key.pem", nil)
}
whispered secrets http://slides.games-with-brains.net/32
tcp/tls server
33
package main
import "crypto/rand"
import "crypto/tls"
import . "fmt"
func main() {
Listen(":443", ConfigTLS("scert", "skey"), func(c *tls.Conn) {
Fprintln(c, "hello world")
})
}
func Listen(a string, conf *tls.Config, f func(*tls.Conn)) {
if listener, e := tls.Listen("tcp", a, conf); e == nil {
for {
if connection, e := listener.Accept(); e == nil {
go func(c *tls.Conn) {
defer c.Close()
f(c)
}(connection.(*tls.Conn))
}
}
}
}
func ConfigTLS(c, k string) (r *tls.Config) {
if cert, e := tls.LoadX509KeyPair(c, k); e == nil {
r = &tls.Config{
Certificates: []tls.Certificate{ cert },
Rand: rand.Reader,
}
}
return
}
whispered secrets http://slides.games-with-brains.net/34
package main
import "crypto/rand"
import "crypto/tls"
import . "fmt"
func main() {
Listen(":443", ConfigTLS("scert", "skey"), func(c *tls.Conn) {
Fprintln(c, "hello world")
})
}
func Listen(a string, conf *tls.Config, f func(*tls.Conn)) {
if listener, e := tls.Listen("tcp", a, conf); e == nil {
for {
if connection, e := listener.Accept(); e == nil {
go func(c *tls.Conn) {
defer c.Close()
f(c)
}(connection.(*tls.Conn))
}
}
}
}
func ConfigTLS(c, k string) (r *tls.Config) {
if cert, e := tls.LoadX509KeyPair(c, k); e == nil {
r = &tls.Config{
Certificates: []tls.Certificate{ cert },
Rand: rand.Reader,
}
}
return
}
whispered secrets http://slides.games-with-brains.net/35
package main
import "crypto/rand"
import "crypto/tls"
import . "fmt"
func main() {
Listen(":443", ConfigTLS("scert", "skey"), func(c *tls.Conn) {
Fprintln(c, "hello world")
})
}
func Listen(a string, conf *tls.Config, f func(*tls.Conn)) {
if listener, e := tls.Listen("tcp", a, conf); e == nil {
for {
if connection, e := listener.Accept(); e == nil {
go func(c *tls.Conn) {
defer c.Close()
f(c)
}(connection.(*tls.Conn))
}
}
}
}
func ConfigTLS(c, k string) (r *tls.Config) {
if cert, e := tls.LoadX509KeyPair(c, k); e == nil {
r = &tls.Config{
Certificates: []tls.Certificate{ cert },
Rand: rand.Reader,
}
}
return
}
whispered secrets http://slides.games-with-brains.net/36
tcp/tls client
37
package main
import . "fmt"
import "bufio"
import "net"
import “crypto/tls"
func main() {
Dial(":1025", ConfigTLS("ccert", "ckey"), func(c net.Conn) {
if m, e := bufio.NewReader(c).ReadString('n'); e == nil {
Printf(m)
}
})
}
func ConfigTLS(c, k string) (r *tls.Config) {
if cert, e := tls.LoadX509KeyPair(c, k); e == nil {
r = &tls.Config{
Certificates: []tls.Certificate{ cert },
InsecureSkipVerify: true,
}
}
return
}
func Dial(a string, conf *tls.Config, f func(net.Conn)) {
if c, e := tls.Dial("tcp", a, conf); e == nil {
defer c.Close()
f(c)
}
}
whispered secrets http://slides.games-with-brains.net/38
package main
import . "fmt"
import "bufio"
import "net"
import “crypto/tls"
func main() {
Dial(":1025", ConfigTLS("ccert", "ckey"), func(c net.Conn) {
if m, e := bufio.NewReader(c).ReadString('n'); e == nil {
Printf(m)
}
})
}
func ConfigTLS(c, k string) (r *tls.Config) {
if cert, e := tls.LoadX509KeyPair(c, k); e == nil {
r = &tls.Config{
Certificates: []tls.Certificate{ cert },
InsecureSkipVerify: false,
}
}
return
}
func Dial(a string, conf *tls.Config, f func(net.Conn)) {
if c, e := tls.Dial("tcp", a, conf); e == nil {
defer c.Close()
f(c)
}
}
whispered secrets http://slides.games-with-brains.net/39
package main
import . "fmt"
import "bufio"
import "net"
import “crypto/tls"
func main() {
Dial(":1025", ConfigTLS("ccert", "ckey"), func(c net.Conn) {
if m, e := bufio.NewReader(c).ReadString('n'); e == nil {
Printf(m)
}
})
}
func ConfigTLS(c, k string) (r *tls.Config) {
if cert, e := tls.LoadX509KeyPair(c, k); e == nil {
r = &tls.Config{
Certificates: []tls.Certificate{ cert },
InsecureSkipVerify: true,
}
}
return
}
func Dial(a string, conf *tls.Config, f func(net.Conn)) {
if c, e := tls.Dial("tcp", a, conf); e == nil {
defer c.Close()
f(c)
}
}
whispered secrets http://slides.games-with-brains.net/40
udp/aes server
41
package main
import "crypto/aes"
import "crypto/cipher"
import "crypto/rand"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) {
if m, e := Encrypt("Hello World", AES_KEY); e == nil {
c.WriteToUDP(m, a)
}
})
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
func Quantise(m string) (b []byte, e error) {
b = append(b, m...)
if p := len(b) % aes.BlockSize; p != 0 {
p = aes.BlockSize - p
// this is insecure and inflexible as we're padding with NUL
b = append(b, make([]byte, p)...)
}
return
}
func IV() (b []byte, e error) {
b = make([]byte, aes.BlockSize)
_, e = rand.Read(b)
return
}
func Encrypt(m, k string) (o []byte, e error) {
if o, e = Quantise([]byte(m)); e == nil {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
if iv, e = IV(); e == nil {
c := cipher.NewCBCEncrypter(b, iv)
c.CryptBlocks(o, o)
o = append(iv, o...)
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/42
package main
import "crypto/aes"
import "crypto/cipher"
import "crypto/rand"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) {
if m, e := Encrypt("Hello World", AES_KEY); e == nil {
c.WriteToUDP(m, a)
}
})
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
func Quantise(m string) (b []byte, e error) {
b = append(b, m...)
if p := len(b) % aes.BlockSize; p != 0 {
p = aes.BlockSize - p
// this is insecure and inflexible as we're padding with NUL
b = append(b, make([]byte, p)...)
}
return
}
func IV() (b []byte, e error) {
b = make([]byte, aes.BlockSize)
_, e = rand.Read(b)
return
}
func Encrypt(m, k string) (o []byte, e error) {
if o, e = Quantise([]byte(m)); e == nil {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
if iv, e = IV(); e == nil {
c := cipher.NewCBCEncrypter(b, iv)
c.CryptBlocks(o, o)
o = append(iv, o...)
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/43
package main
import "crypto/aes"
import "crypto/cipher"
import "crypto/rand"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) {
if m, e := Encrypt("Hello World", AES_KEY); e == nil {
c.WriteToUDP(m, a)
}
})
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
func Quantise(m string) (b []byte, e error) {
b = append(b, m...)
if p := len(b) % aes.BlockSize; p != 0 {
p = aes.BlockSize - p
// this is insecure and inflexible as we're padding with NUL
b = append(b, make([]byte, p)...)
}
return
}
func IV() (b []byte, e error) {
b = make([]byte, aes.BlockSize)
_, e = rand.Read(b)
return
}
func Encrypt(m, k string) (o []byte, e error) {
if o, e = Quantise([]byte(m)); e == nil {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
if iv, e = IV(); e == nil {
c := cipher.NewCBCEncrypter(b, iv)
c.CryptBlocks(o, o)
o = append(iv, o...)
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/44
package main
import "crypto/aes"
import "crypto/cipher"
import "crypto/rand"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) {
if m, e := Encrypt("Hello World", AES_KEY); e == nil {
c.WriteToUDP(m, a)
}
})
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
func Quantise(m string) (b []byte, e error) {
b = append(b, m...)
if p := len(b) % aes.BlockSize; p != 0 {
p = aes.BlockSize - p
// this is insecure and inflexible as we're padding with NUL
b = append(b, make([]byte, p)...)
}
return
}
func IV() (b []byte, e error) {
b = make([]byte, aes.BlockSize)
_, e = rand.Read(b)
return
}
func Encrypt(m, k string) (o []byte, e error) {
if o, e = Quantise([]byte(m)); e == nil {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
if iv, e = IV(); e == nil {
c := cipher.NewCBCEncrypter(b, iv)
c.CryptBlocks(o, o)
o = append(iv, o...)
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/45
package main
import "crypto/aes"
import "crypto/cipher"
import "crypto/rand"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) {
if m, e := Encrypt("Hello World", AES_KEY); e == nil {
c.WriteToUDP(m, a)
}
})
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
func Quantise(m string) (b []byte, e error) {
b = append(b, m...)
if p := len(b) % aes.BlockSize; p != 0 {
p = aes.BlockSize - p
// this is insecure and inflexible as we're padding with NUL
b = append(b, make([]byte, p)...)
}
return
}
func IV() (b []byte, e error) {
b = make([]byte, aes.BlockSize)
_, e = rand.Read(b)
return
}
func Encrypt(m, k string) (o []byte, e error) {
if o, e = Quantise([]byte(m)); e == nil {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
if iv, e = IV(); e == nil {
c := cipher.NewCBCEncrypter(b, iv)
c.CryptBlocks(o, o)
o = append(iv, o...)
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/46
udp/aes client
47
package main
import "bufio"
import "crypto/cipher"
import "crypto/aes"
import . "fmt"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Request(":1025", func(c *UDPConn) {
c.Write(make([]byte, 1))
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(m, AES_KEY); e == nil {
Println(string(m))
}
}
})
}
func Decrypt(m []byte, k string) (r string, e error) {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
iv, m = Unpack(m)
c := cipher.NewCBCDecrypter(b, iv)
c.CryptBlocks(m, m)
r = Dequantise(m)
}
return
}
func Unpack(m []byte) (iv, r []byte) {
return m[:aes.BlockSize], m[aes.BlockSize:]
}
func Dequantise(m []byte) string {
var i int
for i = len(m) - 1; i > 0 && m[i] == 0; i-- {}
return string(m[:i + 1])
}
func Request(a string, f func(Conn)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
f(conn)
}
}
}
whispered secrets http://slides.games-with-brains.net/48
package main
import "bufio"
import "crypto/cipher"
import "crypto/aes"
import . "fmt"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Request(":1025", func(c *UDPConn) {
c.Write(make([]byte, 1))
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(m, AES_KEY); e == nil {
Println(string(m))
}
}
})
}
func Decrypt(m []byte, k string) (r string, e error) {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
iv, m = Unpack(m)
c := cipher.NewCBCDecrypter(b, iv)
c.CryptBlocks(m, m)
r = Dequantise(m)
}
return
}
func Unpack(m []byte) (iv, r []byte) {
return m[:aes.BlockSize], m[aes.BlockSize:]
}
func Dequantise(m []byte) string {
var i int
for i = len(m) - 1; i > 0 && m[i] == 0; i-- {}
return string(m[:i + 1])
}
func Request(a string, f func(Conn)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
f(conn)
}
}
}
whispered secrets http://slides.games-with-brains.net/49
package main
import "bufio"
import "crypto/cipher"
import "crypto/aes"
import . "fmt"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Request(":1025", func(c *UDPConn) {
c.Write(make([]byte, 1))
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(m, AES_KEY); e == nil {
Println(string(m))
}
}
})
}
func Decrypt(m []byte, k string) (r string, e error) {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
iv, m = Unpack(m)
c := cipher.NewCBCDecrypter(b, iv)
c.CryptBlocks(m, m)
r = Dequantise(m)
}
return
}
func Unpack(m []byte) (iv, r []byte) {
return m[:aes.BlockSize], m[aes.BlockSize:]
}
func Dequantise(m []byte) string {
var i int
for i = len(m) - 1; i > 0 && m[i] == 0; i-- {}
return string(m[:i + 1])
}
func Request(a string, f func(Conn)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
f(conn)
}
}
}
whispered secrets http://slides.games-with-brains.net/50
package main
import "bufio"
import "crypto/cipher"
import "crypto/aes"
import . "fmt"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Request(":1025", func(c *UDPConn) {
c.Write(make([]byte, 1))
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(m, AES_KEY); e == nil {
Println(string(m))
}
}
})
}
func Decrypt(m []byte, k string) (r string, e error) {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
iv, m = Unpack(m)
c := cipher.NewCBCDecrypter(b, iv)
c.CryptBlocks(m, m)
r = Dequantise(m)
}
return
}
func Unpack(m []byte) (iv, r []byte) {
return m[:aes.BlockSize], m[aes.BlockSize:]
}
func Dequantise(m []byte) string {
var i int
for i = len(m) - 1; i > 0 && m[i] == 0; i-- {}
return string(m[:i + 1])
}
func Request(a string, f func(Conn)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
f(conn)
}
}
}
whispered secrets http://slides.games-with-brains.net/51
package main
import "bufio"
import "crypto/cipher"
import "crypto/aes"
import . "fmt"
import . "net"
const AES_KEY = "0123456789012345"
func main() {
Request(":1025", func(c *UDPConn) {
c.Write(make([]byte, 1))
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(m, AES_KEY); e == nil {
Println(string(m))
}
}
})
}
func Decrypt(m []byte, k string) (r string, e error) {
var b cipher.Block
if b, e = aes.NewCipher([]byte(k)); e == nil {
var iv []byte
iv, m = Unpack(m)
c := cipher.NewCBCDecrypter(b, iv)
c.CryptBlocks(m, m)
r = Dequantise(m)
}
return
}
func Unpack(m []byte) (iv, r []byte) {
return m[:aes.BlockSize], m[aes.BlockSize:]
}
func Dequantise(m []byte) string {
var i int
for i = len(m) - 1; i > 0 && m[i] == 0; i-- {}
return string(m[:i + 1])
}
func Request(a string, f func(Conn)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
f(conn)
}
}
}
whispered secrets http://slides.games-with-brains.net/52
udp/rsa server
53
package main
import . "bytes"
import "crypto/rsa"
import "encoding/gob"
import "net"
func main() {
HELLO_WORLD := []byte("Hello World")
RSA_LABEL := []byte("served")
Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) {
var key rsa.PublicKey
if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil {
if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil {
c.WriteToUDP(m, a)
}
}
return
})
}
func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) {
return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/54
package main
import . "bytes"
import "crypto/rsa"
import "encoding/gob"
import "net"
func main() {
HELLO_WORLD := []byte("Hello World")
RSA_LABEL := []byte("served")
Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) {
var key rsa.PublicKey
if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil {
if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil {
c.WriteToUDP(m, a)
}
}
return
})
}
func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) {
return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/55
udp/rsa client
56
package main
import "crypto/rsa"
import "crypto/rand"
import "crypto/sha1"
import "crypto/x509"
import "bytes"
import "encoding/gob"
import "encoding/pem"
import “io/ioutil"
import . "fmt"
import . "net"
func main() {
Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) {
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(k, m, []byte("served")); e == nil {
Println(string(m))
}
}
})
}
func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) {
if file, e := ioutil.ReadFile(file); e == nil {
if block, _ := pem.Decode(file); block != nil {
if block.Type == "RSA PRIVATE KEY" {
r, e = x509.ParsePKCS1PrivateKey(block.Bytes)
}
}
}
return
}
func Request(a, file string, f func(*UDPConn, *PrivateKey)) {
if k, e := LoadPrivateKey(file); e == nil {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
SendKey(conn, k.PublicKey, func() {
f(conn, k)
})
}
}
}
}
func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) {
return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) {
var b bytes.Buffer
if e := gob.NewEncoder(&b).Encode(k); e == nil {
if _, e = c.Write(b.Bytes()); e == nil {
f()
}
}
}
whispered secrets http://slides.games-with-brains.net/57
package main
import "crypto/rsa"
import "crypto/rand"
import "crypto/sha1"
import "crypto/x509"
import "bytes"
import "encoding/gob"
import "encoding/pem"
import “io/ioutil"
import . "fmt"
import . "net"
func main() {
Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) {
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(k, m, []byte("served")); e == nil {
Println(string(m))
}
}
})
}
func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) {
if file, e := ioutil.ReadFile(file); e == nil {
if block, _ := pem.Decode(file); block != nil {
if block.Type == "RSA PRIVATE KEY" {
r, e = x509.ParsePKCS1PrivateKey(block.Bytes)
}
}
}
return
}
func Request(a, file string, f func(*UDPConn, *PrivateKey)) {
if k, e := LoadPrivateKey(file); e == nil {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
SendKey(conn, k.PublicKey, func() {
f(conn, k)
})
}
}
}
}
func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) {
return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) {
var b bytes.Buffer
if e := gob.NewEncoder(&b).Encode(k); e == nil {
if _, e = c.Write(b.Bytes()); e == nil {
f()
}
}
}
whispered secrets http://slides.games-with-brains.net/58
package main
import "crypto/rsa"
import "crypto/rand"
import "crypto/sha1"
import "crypto/x509"
import "bytes"
import "encoding/gob"
import "encoding/pem"
import “io/ioutil"
import . "fmt"
import . "net"
func main() {
Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) {
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(k, m, []byte("served")); e == nil {
Println(string(m))
}
}
})
}
func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) {
if file, e := ioutil.ReadFile(file); e == nil {
if block, _ := pem.Decode(file); block != nil {
if block.Type == "RSA PRIVATE KEY" {
r, e = x509.ParsePKCS1PrivateKey(block.Bytes)
}
}
}
return
}
func Request(a, file string, f func(*UDPConn, *PrivateKey)) {
if k, e := LoadPrivateKey(file); e == nil {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
SendKey(conn, k.PublicKey, func() {
f(conn, k)
})
}
}
}
}
func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) {
return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) {
var b bytes.Buffer
if e := gob.NewEncoder(&b).Encode(k); e == nil {
if _, e = c.Write(b.Bytes()); e == nil {
f()
}
}
}
whispered secrets http://slides.games-with-brains.net/59
aes + rsa —> hybrid crypto
60
aes + hmac —> signature
61
crypto + signature —> trust
62
hmac/rsa signing
63
package main
import . "bytes"
import "crypto/hmac"
import "crypto/rsa"
import "crypto/sha256"
import "encoding/base64"
import "encoding/gob"
import "net"
func main() {
HELLO_WORLD := []byte("Hello World")
RSA_LABEL := []byte("served")
SIGNING_KEY := []byte("signature")
Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) {
var key rsa.PublicKey
if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil {
if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil {
m = append(Sign(HELLO_WORLD, SIGNING_KEY), m)
c.WriteToUDP(m, a)
}
}
return
})
}
func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) {
return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
func Sign(message string, key []byte) string {
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/64
package main
import . "bytes"
import "crypto/hmac"
import "crypto/rsa"
import "crypto/sha256"
import "encoding/base64"
import "encoding/gob"
import "net"
func main() {
HELLO_WORLD := []byte("Hello World")
RSA_LABEL := []byte("served")
SIGNING_KEY := []byte("signature")
Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) {
var key rsa.PublicKey
if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil {
if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil {
m = append(Sign(HELLO_WORLD, SIGNING_KEY), m)
c.WriteToUDP(m, a)
}
}
return
})
}
func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) {
return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
func Sign(message string, key []byte) string {
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := ListenUDP("udp", address); e == nil {
for b := make([]byte, 1024); ; b = make([]byte, 1024) {
if n, client, e := conn.ReadFromUDP(b); e == nil {
go f(conn, client, b[:n])
}
}
}
}
return
}
whispered secrets http://slides.games-with-brains.net/65
hmac/rsa validation
66
package main
import "crypto/hmac"
import "crypto/rsa"
import "crypto/rand"
import "crypto/sha1"
import "crypto/sha256"
import "crypto/x509"
import "bytes"
import "encoding/base64"
import "encoding/gob"
import "encoding/pem"
import “io/ioutil"
import . "fmt"
import . "net"
func main() {
Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) {
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(k, m[44:], []byte("served")); e == nil {
s, _ := base64.URLEncoding.DecodeString(string(m[:44)))
v := hmac.Equal(s, Sign(m, "signature"))
Print(string(m), "[valid:", v,"]”)
}
}
})
}
func Sign(message string, key []byte) string {
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) {
var b bytes.Buffer
if e := gob.NewEncoder(&b).Encode(k); e == nil {
if _, e = c.Write(b.Bytes()); e == nil {
f()
}
}
}
func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) {
if file, e := ioutil.ReadFile(file); e == nil {
if block, _ := pem.Decode(file); block != nil {
if block.Type == "RSA PRIVATE KEY" {
r, e = x509.ParsePKCS1PrivateKey(block.Bytes)
}
}
}
return
}
func Request(a, file string, f func(*UDPConn, *PrivateKey)) {
if k, e := LoadPrivateKey(file); e == nil {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
SendKey(conn, k.PublicKey, func() {
f(conn, k)
})
}
}
}
}
func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) {
return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
whispered secrets http://slides.games-with-brains.net/67
package main
import "crypto/hmac"
import "crypto/rsa"
import "crypto/rand"
import "crypto/sha1"
import "crypto/sha256"
import "crypto/x509"
import "bytes"
import "encoding/base64"
import "encoding/gob"
import "encoding/pem"
import “io/ioutil"
import . "fmt"
import . "net"
func main() {
Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) {
if m, e := ReadStream(c); e == nil {
if m, e := Decrypt(k, m[44:], []byte("served")); e == nil {
s, _ := base64.URLEncoding.DecodeString(string(m[:44)))
v := hmac.Equal(s, Sign(m, "signature"))
Print(string(m), "[valid:", v,"]”)
}
}
})
}
func Sign(message string, key []byte) string {
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) {
var b bytes.Buffer
if e := gob.NewEncoder(&b).Encode(k); e == nil {
if _, e = c.Write(b.Bytes()); e == nil {
f()
}
}
}
func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) {
if file, e := ioutil.ReadFile(file); e == nil {
if block, _ := pem.Decode(file); block != nil {
if block.Type == "RSA PRIVATE KEY" {
r, e = x509.ParsePKCS1PrivateKey(block.Bytes)
}
}
}
return
}
func Request(a, file string, f func(*UDPConn, *PrivateKey)) {
if k, e := LoadPrivateKey(file); e == nil {
if address, e := ResolveUDPAddr("udp", a); e == nil {
if conn, e := DialUDP("udp", nil, address); e == nil {
defer conn.Close()
SendKey(conn, k.PublicKey, func() {
f(conn, k)
})
}
}
}
}
func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) {
return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l)
}
whispered secrets http://slides.games-with-brains.net/68
encrypt all passwords
• accept unicode to expand the symbol space
• hash every new password before it’s submitted
• always use a cryptograpically secure hash (HMAC)
• and a fresh HMAC key for each password (which you must store)
• salt the resulting hash when you receive it (and store the salt)
• then hash again before storing in your database
69
require multi-factor authentication
• have the user submit their password over a secure channel
• then send them a confirmation code out-of-band
• that’s an agreed trust anchor acting as a shared secret
• the confirmation code should be big enough to generate a HMAC
• and only the HMAC should be submitted
• now you have two secure channels based on shared secrets
70
encrypt all storage
• secured transport is useless without secured data stores
• encrypt all sensitive fields - that probably means all fields
• and store HMACs for desired search terms
• otherwise your black box is secure but unsearchable
• make sure you use different roles for reading, writing and searching
• that’s right, your datastore is also a set of secure streams
71
privacy ——> operational rules
anchor trust internally
• establish a private certificate authority
• assign fine-grained roles to different components
• audit requirements, code, operations, security logs
• never deploy without a credible security audit
• and make those deployments immutable
• security audits best done by third parties with an attacker mentality
73
slideshare://feyeleanor

Más contenido relacionado

La actualidad más candente

How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giantsIan Barber
 
Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmerEleanor McHugh
 
ikh331-06-distributed-programming
ikh331-06-distributed-programmingikh331-06-distributed-programming
ikh331-06-distributed-programmingAnung Ariwibowo
 
Udp socket programming(Florian)
Udp socket programming(Florian)Udp socket programming(Florian)
Udp socket programming(Florian)Flor Ian
 
Computer Networks Lab File
Computer Networks Lab FileComputer Networks Lab File
Computer Networks Lab FileKandarp Tiwari
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineMovel
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data StructuresPDX Web & Design
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency명신 김
 
Assignment no39
Assignment no39Assignment no39
Assignment no39Jay Patel
 
Chatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptopChatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptopyayaria
 
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014Fantix King 王川
 
Basic NLP with Python and NLTK
Basic NLP with Python and NLTKBasic NLP with Python and NLTK
Basic NLP with Python and NLTKFrancesco Bruni
 
Creating an Arduino Web Server from scratch hardware and software
Creating an Arduino Web Server from scratch hardware and softwareCreating an Arduino Web Server from scratch hardware and software
Creating an Arduino Web Server from scratch hardware and softwareJustin Mclean
 

La actualidad más candente (20)

Binomial heap
Binomial heapBinomial heap
Binomial heap
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
 
Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmer
 
ikh331-06-distributed-programming
ikh331-06-distributed-programmingikh331-06-distributed-programming
ikh331-06-distributed-programming
 
Usp
UspUsp
Usp
 
Introducing to Asynchronous Programming
Introducing to Asynchronous  ProgrammingIntroducing to Asynchronous  Programming
Introducing to Asynchronous Programming
 
part2
part2part2
part2
 
Udp socket programming(Florian)
Udp socket programming(Florian)Udp socket programming(Florian)
Udp socket programming(Florian)
 
Computer Networks Lab File
Computer Networks Lab FileComputer Networks Lab File
Computer Networks Lab File
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy Cresine
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data Structures
 
Kamailio and VoIP Wild World
Kamailio and VoIP Wild WorldKamailio and VoIP Wild World
Kamailio and VoIP Wild World
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency
 
Assignment no39
Assignment no39Assignment no39
Assignment no39
 
Chatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptopChatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptop
 
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
 
Basic NLP with Python and NLTK
Basic NLP with Python and NLTKBasic NLP with Python and NLTK
Basic NLP with Python and NLTK
 
C++ L08-Classes Part1
C++ L08-Classes Part1C++ L08-Classes Part1
C++ L08-Classes Part1
 
Npc14
Npc14Npc14
Npc14
 
Creating an Arduino Web Server from scratch hardware and software
Creating an Arduino Web Server from scratch hardware and softwareCreating an Arduino Web Server from scratch hardware and software
Creating an Arduino Web Server from scratch hardware and software
 

Similar a Whispered secrets

OpenSSL programming (still somewhat initial version)
OpenSSL programming (still somewhat initial version)OpenSSL programming (still somewhat initial version)
OpenSSL programming (still somewhat initial version)Shteryana Shopova
 
OpenSSL Basic Function Call Flow
OpenSSL Basic Function Call FlowOpenSSL Basic Function Call Flow
OpenSSL Basic Function Call FlowWilliam Lee
 
SSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and SchedulingSSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and SchedulingDavid Evans
 
Secure .NET programming
Secure .NET programmingSecure .NET programming
Secure .NET programmingAnte Gulam
 
IT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdf
IT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdfIT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdf
IT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdfDhanuskarSankar1
 
Dynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency PlanningDynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency PlanningSean Chittenden
 
Sasha Romijn - Everything I always wanted to know about crypto, but never tho...
Sasha Romijn - Everything I always wanted to know about crypto, but never tho...Sasha Romijn - Everything I always wanted to know about crypto, but never tho...
Sasha Romijn - Everything I always wanted to know about crypto, but never tho...Codemotion
 
12 symmetric key cryptography
12   symmetric key cryptography12   symmetric key cryptography
12 symmetric key cryptographydrewz lin
 
Python para equipos de ciberseguridad(pycones)
Python para equipos de ciberseguridad(pycones)Python para equipos de ciberseguridad(pycones)
Python para equipos de ciberseguridad(pycones)Jose Manuel Ortega Candel
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in rubyHiroshi Nakamura
 
Using Kamailio for Scalability and Security
Using Kamailio for Scalability and SecurityUsing Kamailio for Scalability and Security
Using Kamailio for Scalability and SecurityFred Posner
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful weddingStéphane Wirtel
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Siouxnikomatsakis
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+ConFoo
 
Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2VMware Tanzu
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Remy Sharp
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02PL dream
 

Similar a Whispered secrets (20)

OpenSSL programming (still somewhat initial version)
OpenSSL programming (still somewhat initial version)OpenSSL programming (still somewhat initial version)
OpenSSL programming (still somewhat initial version)
 
OpenSSL Basic Function Call Flow
OpenSSL Basic Function Call FlowOpenSSL Basic Function Call Flow
OpenSSL Basic Function Call Flow
 
SSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and SchedulingSSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and Scheduling
 
Secure .NET programming
Secure .NET programmingSecure .NET programming
Secure .NET programming
 
IT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdf
IT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdfIT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdf
IT8761-SECURITY LABORATORY-590519304-IT8761 security labmanual.pdf
 
Dynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency PlanningDynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency Planning
 
Django cryptography
Django cryptographyDjango cryptography
Django cryptography
 
Sasha Romijn - Everything I always wanted to know about crypto, but never tho...
Sasha Romijn - Everything I always wanted to know about crypto, but never tho...Sasha Romijn - Everything I always wanted to know about crypto, but never tho...
Sasha Romijn - Everything I always wanted to know about crypto, but never tho...
 
12 symmetric key cryptography
12   symmetric key cryptography12   symmetric key cryptography
12 symmetric key cryptography
 
Python para equipos de ciberseguridad(pycones)
Python para equipos de ciberseguridad(pycones)Python para equipos de ciberseguridad(pycones)
Python para equipos de ciberseguridad(pycones)
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in ruby
 
Using Kamailio for Scalability and Security
Using Kamailio for Scalability and SecurityUsing Kamailio for Scalability and Security
Using Kamailio for Scalability and Security
 
Network Security
Network SecurityNetwork Security
Network Security
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Sioux
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2
 
Python for Penetration testers
Python for Penetration testersPython for Penetration testers
Python for Penetration testers
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
 

Más de Eleanor McHugh

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdfEleanor McHugh
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsEleanor McHugh
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityEleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveEleanor McHugh
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionEleanor McHugh
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]Eleanor McHugh
 
An introduction to functional programming with go
An introduction to functional programming with goAn introduction to functional programming with go
An introduction to functional programming with goEleanor McHugh
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxEleanor McHugh
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored SpacesEleanor McHugh
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignEleanor McHugh
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by designEleanor McHugh
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trustEleanor McHugh
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoEleanor McHugh
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleEleanor McHugh
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionEleanor McHugh
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoEleanor McHugh
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goEleanor McHugh
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountabilityEleanor McHugh
 

Más de Eleanor McHugh (20)

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
 
An introduction to functional programming with go
An introduction to functional programming with goAn introduction to functional programming with go
An introduction to functional programming with go
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
 
Hello Go
Hello GoHello Go
Hello Go
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in go
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
 

Último

Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 

Último (20)

Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 

Whispered secrets

  • 4. we all have secrets and these secrets matter to us that’s what makes them secrets software should keep our secrets
  • 5. some secrets are awful conspiracy infidelity criminality
  • 6. some secrets are banal bank account numbers embarrassing incidents sexual preferences
  • 7. secrecy should be absolute our tech must protect the awful or it won’t protect the banal
  • 8. but there are laws we must comply with these assist the legitimate deny the illegitimate
  • 10. privacy is not absolute privacy requires mutual trust mutual trust is a contract and contracts can be broken
  • 11. famous broken contracts Ashley-Madison Carphone Warehouse Office of Personnel Management
  • 12. today’s topic is applied paranoia
  • 13. paranoia Pronunciation: /ˌparəәˈnɔɪəә/ noun {mass noun} A mental condition characterized by delusions of persecution, unwarranted jealousy, or exaggerated self-importance, typically worked into an organized system. It may be an aspect of chronic personality disorder, of drug abuse, or of a serious condition such as schizophrenia in which the person loses touch with reality. Unjustified suspicion and mistrust of other people: mild paranoia afflicts all prime ministers 13
  • 14.
  • 15.
  • 16.
  • 17. paranoia Pronunciation: /ˌparəәˈnɔɪəә/ noun {mass noun} The perfectly reasonable belief that someone, somewhere is watching your online behaviour with malicious and/or voyeuristic intent. It may be a result of reading a Hacking Exposed or Hacking for Dummies publication, experiencing the fallout from identity theft, or shopping with bitcoin. Justified suspicion and mistrust of other people: chronic paranoia afflicts all information security professionals accute paranoia afflicts the victims of hacking 17
  • 18. 18
  • 19. we have to trust governments governments are privileged if we don’t obey they can hurt us not much we can do about that 19
  • 20. 20
  • 21. our users have to trust us our services are privileged they store real-world secrets and identifying metadata 21
  • 22. but who can we trust? technology bars the gates but people create the bars and people have to monitor them 22
  • 23. so what do we do? dev practices architecture operational rules 23
  • 24. privacy ——> dev practices
  • 28. encrypt all transports • establish a secure channel by exchanging public keys • and check their validity against trusted certificates (SSL, TLS, etc.) • as an added measure pin these certificates (like SSH pins keys) • then exchange symmetric keys for a private secure channel • change these keys frequently (cheap cipher streams) • and pin each distinct message to a distinct key (one-time pads) 28
  • 30. package main import . "fmt" import . "net/http" const ADDRESS = ":443" func main() { message := "hello world" HandleFunc("/hello", func(w ResponseWriter, r *Request) { w.Header().Set("Content-Type", "text/plain") Fprintf(w, message) }) ListenAndServeTLS(ADDRESS, "cert.pem", "key.pem", nil) } whispered secrets http://slides.games-with-brains.net/30
  • 31. package main import . "fmt" import . "net/http" const ADDRESS = ":443" func main() { message := "hello world" HandleFunc("/hello", func(w ResponseWriter, r *Request) { w.Header().Set("Content-Type", "text/plain") Fprintf(w, message) }) ListenAndServeTLS(ADDRESS, "cert.pem", "key.pem", nil) } whispered secrets http://slides.games-with-brains.net/31
  • 32. package main import . "fmt" import . "net/http" const ADDRESS = ":443" func main() { message := "hello world" HandleFunc("/hello", func(w ResponseWriter, r *Request) { w.Header().Set("Content-Type", "text/plain") Fprintf(w, message) }) ListenAndServeTLS(ADDRESS, "cert.pem", "key.pem", nil) } whispered secrets http://slides.games-with-brains.net/32
  • 34. package main import "crypto/rand" import "crypto/tls" import . "fmt" func main() { Listen(":443", ConfigTLS("scert", "skey"), func(c *tls.Conn) { Fprintln(c, "hello world") }) } func Listen(a string, conf *tls.Config, f func(*tls.Conn)) { if listener, e := tls.Listen("tcp", a, conf); e == nil { for { if connection, e := listener.Accept(); e == nil { go func(c *tls.Conn) { defer c.Close() f(c) }(connection.(*tls.Conn)) } } } } func ConfigTLS(c, k string) (r *tls.Config) { if cert, e := tls.LoadX509KeyPair(c, k); e == nil { r = &tls.Config{ Certificates: []tls.Certificate{ cert }, Rand: rand.Reader, } } return } whispered secrets http://slides.games-with-brains.net/34
  • 35. package main import "crypto/rand" import "crypto/tls" import . "fmt" func main() { Listen(":443", ConfigTLS("scert", "skey"), func(c *tls.Conn) { Fprintln(c, "hello world") }) } func Listen(a string, conf *tls.Config, f func(*tls.Conn)) { if listener, e := tls.Listen("tcp", a, conf); e == nil { for { if connection, e := listener.Accept(); e == nil { go func(c *tls.Conn) { defer c.Close() f(c) }(connection.(*tls.Conn)) } } } } func ConfigTLS(c, k string) (r *tls.Config) { if cert, e := tls.LoadX509KeyPair(c, k); e == nil { r = &tls.Config{ Certificates: []tls.Certificate{ cert }, Rand: rand.Reader, } } return } whispered secrets http://slides.games-with-brains.net/35
  • 36. package main import "crypto/rand" import "crypto/tls" import . "fmt" func main() { Listen(":443", ConfigTLS("scert", "skey"), func(c *tls.Conn) { Fprintln(c, "hello world") }) } func Listen(a string, conf *tls.Config, f func(*tls.Conn)) { if listener, e := tls.Listen("tcp", a, conf); e == nil { for { if connection, e := listener.Accept(); e == nil { go func(c *tls.Conn) { defer c.Close() f(c) }(connection.(*tls.Conn)) } } } } func ConfigTLS(c, k string) (r *tls.Config) { if cert, e := tls.LoadX509KeyPair(c, k); e == nil { r = &tls.Config{ Certificates: []tls.Certificate{ cert }, Rand: rand.Reader, } } return } whispered secrets http://slides.games-with-brains.net/36
  • 38. package main import . "fmt" import "bufio" import "net" import “crypto/tls" func main() { Dial(":1025", ConfigTLS("ccert", "ckey"), func(c net.Conn) { if m, e := bufio.NewReader(c).ReadString('n'); e == nil { Printf(m) } }) } func ConfigTLS(c, k string) (r *tls.Config) { if cert, e := tls.LoadX509KeyPair(c, k); e == nil { r = &tls.Config{ Certificates: []tls.Certificate{ cert }, InsecureSkipVerify: true, } } return } func Dial(a string, conf *tls.Config, f func(net.Conn)) { if c, e := tls.Dial("tcp", a, conf); e == nil { defer c.Close() f(c) } } whispered secrets http://slides.games-with-brains.net/38
  • 39. package main import . "fmt" import "bufio" import "net" import “crypto/tls" func main() { Dial(":1025", ConfigTLS("ccert", "ckey"), func(c net.Conn) { if m, e := bufio.NewReader(c).ReadString('n'); e == nil { Printf(m) } }) } func ConfigTLS(c, k string) (r *tls.Config) { if cert, e := tls.LoadX509KeyPair(c, k); e == nil { r = &tls.Config{ Certificates: []tls.Certificate{ cert }, InsecureSkipVerify: false, } } return } func Dial(a string, conf *tls.Config, f func(net.Conn)) { if c, e := tls.Dial("tcp", a, conf); e == nil { defer c.Close() f(c) } } whispered secrets http://slides.games-with-brains.net/39
  • 40. package main import . "fmt" import "bufio" import "net" import “crypto/tls" func main() { Dial(":1025", ConfigTLS("ccert", "ckey"), func(c net.Conn) { if m, e := bufio.NewReader(c).ReadString('n'); e == nil { Printf(m) } }) } func ConfigTLS(c, k string) (r *tls.Config) { if cert, e := tls.LoadX509KeyPair(c, k); e == nil { r = &tls.Config{ Certificates: []tls.Certificate{ cert }, InsecureSkipVerify: true, } } return } func Dial(a string, conf *tls.Config, f func(net.Conn)) { if c, e := tls.Dial("tcp", a, conf); e == nil { defer c.Close() f(c) } } whispered secrets http://slides.games-with-brains.net/40
  • 42. package main import "crypto/aes" import "crypto/cipher" import "crypto/rand" import . "net" const AES_KEY = "0123456789012345" func main() { Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) { if m, e := Encrypt("Hello World", AES_KEY); e == nil { c.WriteToUDP(m, a) } }) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } func Quantise(m string) (b []byte, e error) { b = append(b, m...) if p := len(b) % aes.BlockSize; p != 0 { p = aes.BlockSize - p // this is insecure and inflexible as we're padding with NUL b = append(b, make([]byte, p)...) } return } func IV() (b []byte, e error) { b = make([]byte, aes.BlockSize) _, e = rand.Read(b) return } func Encrypt(m, k string) (o []byte, e error) { if o, e = Quantise([]byte(m)); e == nil { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte if iv, e = IV(); e == nil { c := cipher.NewCBCEncrypter(b, iv) c.CryptBlocks(o, o) o = append(iv, o...) } } } return } whispered secrets http://slides.games-with-brains.net/42
  • 43. package main import "crypto/aes" import "crypto/cipher" import "crypto/rand" import . "net" const AES_KEY = "0123456789012345" func main() { Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) { if m, e := Encrypt("Hello World", AES_KEY); e == nil { c.WriteToUDP(m, a) } }) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } func Quantise(m string) (b []byte, e error) { b = append(b, m...) if p := len(b) % aes.BlockSize; p != 0 { p = aes.BlockSize - p // this is insecure and inflexible as we're padding with NUL b = append(b, make([]byte, p)...) } return } func IV() (b []byte, e error) { b = make([]byte, aes.BlockSize) _, e = rand.Read(b) return } func Encrypt(m, k string) (o []byte, e error) { if o, e = Quantise([]byte(m)); e == nil { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte if iv, e = IV(); e == nil { c := cipher.NewCBCEncrypter(b, iv) c.CryptBlocks(o, o) o = append(iv, o...) } } } return } whispered secrets http://slides.games-with-brains.net/43
  • 44. package main import "crypto/aes" import "crypto/cipher" import "crypto/rand" import . "net" const AES_KEY = "0123456789012345" func main() { Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) { if m, e := Encrypt("Hello World", AES_KEY); e == nil { c.WriteToUDP(m, a) } }) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } func Quantise(m string) (b []byte, e error) { b = append(b, m...) if p := len(b) % aes.BlockSize; p != 0 { p = aes.BlockSize - p // this is insecure and inflexible as we're padding with NUL b = append(b, make([]byte, p)...) } return } func IV() (b []byte, e error) { b = make([]byte, aes.BlockSize) _, e = rand.Read(b) return } func Encrypt(m, k string) (o []byte, e error) { if o, e = Quantise([]byte(m)); e == nil { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte if iv, e = IV(); e == nil { c := cipher.NewCBCEncrypter(b, iv) c.CryptBlocks(o, o) o = append(iv, o...) } } } return } whispered secrets http://slides.games-with-brains.net/44
  • 45. package main import "crypto/aes" import "crypto/cipher" import "crypto/rand" import . "net" const AES_KEY = "0123456789012345" func main() { Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) { if m, e := Encrypt("Hello World", AES_KEY); e == nil { c.WriteToUDP(m, a) } }) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } func Quantise(m string) (b []byte, e error) { b = append(b, m...) if p := len(b) % aes.BlockSize; p != 0 { p = aes.BlockSize - p // this is insecure and inflexible as we're padding with NUL b = append(b, make([]byte, p)...) } return } func IV() (b []byte, e error) { b = make([]byte, aes.BlockSize) _, e = rand.Read(b) return } func Encrypt(m, k string) (o []byte, e error) { if o, e = Quantise([]byte(m)); e == nil { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte if iv, e = IV(); e == nil { c := cipher.NewCBCEncrypter(b, iv) c.CryptBlocks(o, o) o = append(iv, o...) } } } return } whispered secrets http://slides.games-with-brains.net/45
  • 46. package main import "crypto/aes" import "crypto/cipher" import "crypto/rand" import . "net" const AES_KEY = "0123456789012345" func main() { Serve(":1025", func(c *UDPConn, a *UDPAddr, b []byte) { if m, e := Encrypt("Hello World", AES_KEY); e == nil { c.WriteToUDP(m, a) } }) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } func Quantise(m string) (b []byte, e error) { b = append(b, m...) if p := len(b) % aes.BlockSize; p != 0 { p = aes.BlockSize - p // this is insecure and inflexible as we're padding with NUL b = append(b, make([]byte, p)...) } return } func IV() (b []byte, e error) { b = make([]byte, aes.BlockSize) _, e = rand.Read(b) return } func Encrypt(m, k string) (o []byte, e error) { if o, e = Quantise([]byte(m)); e == nil { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte if iv, e = IV(); e == nil { c := cipher.NewCBCEncrypter(b, iv) c.CryptBlocks(o, o) o = append(iv, o...) } } } return } whispered secrets http://slides.games-with-brains.net/46
  • 48. package main import "bufio" import "crypto/cipher" import "crypto/aes" import . "fmt" import . "net" const AES_KEY = "0123456789012345" func main() { Request(":1025", func(c *UDPConn) { c.Write(make([]byte, 1)) if m, e := ReadStream(c); e == nil { if m, e := Decrypt(m, AES_KEY); e == nil { Println(string(m)) } } }) } func Decrypt(m []byte, k string) (r string, e error) { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte iv, m = Unpack(m) c := cipher.NewCBCDecrypter(b, iv) c.CryptBlocks(m, m) r = Dequantise(m) } return } func Unpack(m []byte) (iv, r []byte) { return m[:aes.BlockSize], m[aes.BlockSize:] } func Dequantise(m []byte) string { var i int for i = len(m) - 1; i > 0 && m[i] == 0; i-- {} return string(m[:i + 1]) } func Request(a string, f func(Conn)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() f(conn) } } } whispered secrets http://slides.games-with-brains.net/48
  • 49. package main import "bufio" import "crypto/cipher" import "crypto/aes" import . "fmt" import . "net" const AES_KEY = "0123456789012345" func main() { Request(":1025", func(c *UDPConn) { c.Write(make([]byte, 1)) if m, e := ReadStream(c); e == nil { if m, e := Decrypt(m, AES_KEY); e == nil { Println(string(m)) } } }) } func Decrypt(m []byte, k string) (r string, e error) { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte iv, m = Unpack(m) c := cipher.NewCBCDecrypter(b, iv) c.CryptBlocks(m, m) r = Dequantise(m) } return } func Unpack(m []byte) (iv, r []byte) { return m[:aes.BlockSize], m[aes.BlockSize:] } func Dequantise(m []byte) string { var i int for i = len(m) - 1; i > 0 && m[i] == 0; i-- {} return string(m[:i + 1]) } func Request(a string, f func(Conn)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() f(conn) } } } whispered secrets http://slides.games-with-brains.net/49
  • 50. package main import "bufio" import "crypto/cipher" import "crypto/aes" import . "fmt" import . "net" const AES_KEY = "0123456789012345" func main() { Request(":1025", func(c *UDPConn) { c.Write(make([]byte, 1)) if m, e := ReadStream(c); e == nil { if m, e := Decrypt(m, AES_KEY); e == nil { Println(string(m)) } } }) } func Decrypt(m []byte, k string) (r string, e error) { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte iv, m = Unpack(m) c := cipher.NewCBCDecrypter(b, iv) c.CryptBlocks(m, m) r = Dequantise(m) } return } func Unpack(m []byte) (iv, r []byte) { return m[:aes.BlockSize], m[aes.BlockSize:] } func Dequantise(m []byte) string { var i int for i = len(m) - 1; i > 0 && m[i] == 0; i-- {} return string(m[:i + 1]) } func Request(a string, f func(Conn)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() f(conn) } } } whispered secrets http://slides.games-with-brains.net/50
  • 51. package main import "bufio" import "crypto/cipher" import "crypto/aes" import . "fmt" import . "net" const AES_KEY = "0123456789012345" func main() { Request(":1025", func(c *UDPConn) { c.Write(make([]byte, 1)) if m, e := ReadStream(c); e == nil { if m, e := Decrypt(m, AES_KEY); e == nil { Println(string(m)) } } }) } func Decrypt(m []byte, k string) (r string, e error) { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte iv, m = Unpack(m) c := cipher.NewCBCDecrypter(b, iv) c.CryptBlocks(m, m) r = Dequantise(m) } return } func Unpack(m []byte) (iv, r []byte) { return m[:aes.BlockSize], m[aes.BlockSize:] } func Dequantise(m []byte) string { var i int for i = len(m) - 1; i > 0 && m[i] == 0; i-- {} return string(m[:i + 1]) } func Request(a string, f func(Conn)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() f(conn) } } } whispered secrets http://slides.games-with-brains.net/51
  • 52. package main import "bufio" import "crypto/cipher" import "crypto/aes" import . "fmt" import . "net" const AES_KEY = "0123456789012345" func main() { Request(":1025", func(c *UDPConn) { c.Write(make([]byte, 1)) if m, e := ReadStream(c); e == nil { if m, e := Decrypt(m, AES_KEY); e == nil { Println(string(m)) } } }) } func Decrypt(m []byte, k string) (r string, e error) { var b cipher.Block if b, e = aes.NewCipher([]byte(k)); e == nil { var iv []byte iv, m = Unpack(m) c := cipher.NewCBCDecrypter(b, iv) c.CryptBlocks(m, m) r = Dequantise(m) } return } func Unpack(m []byte) (iv, r []byte) { return m[:aes.BlockSize], m[aes.BlockSize:] } func Dequantise(m []byte) string { var i int for i = len(m) - 1; i > 0 && m[i] == 0; i-- {} return string(m[:i + 1]) } func Request(a string, f func(Conn)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() f(conn) } } } whispered secrets http://slides.games-with-brains.net/52
  • 54. package main import . "bytes" import "crypto/rsa" import "encoding/gob" import "net" func main() { HELLO_WORLD := []byte("Hello World") RSA_LABEL := []byte("served") Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) { var key rsa.PublicKey if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil { if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil { c.WriteToUDP(m, a) } } return }) } func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) { return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } whispered secrets http://slides.games-with-brains.net/54
  • 55. package main import . "bytes" import "crypto/rsa" import "encoding/gob" import "net" func main() { HELLO_WORLD := []byte("Hello World") RSA_LABEL := []byte("served") Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) { var key rsa.PublicKey if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil { if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil { c.WriteToUDP(m, a) } } return }) } func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) { return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } whispered secrets http://slides.games-with-brains.net/55
  • 57. package main import "crypto/rsa" import "crypto/rand" import "crypto/sha1" import "crypto/x509" import "bytes" import "encoding/gob" import "encoding/pem" import “io/ioutil" import . "fmt" import . "net" func main() { Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) { if m, e := ReadStream(c); e == nil { if m, e := Decrypt(k, m, []byte("served")); e == nil { Println(string(m)) } } }) } func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) { if file, e := ioutil.ReadFile(file); e == nil { if block, _ := pem.Decode(file); block != nil { if block.Type == "RSA PRIVATE KEY" { r, e = x509.ParsePKCS1PrivateKey(block.Bytes) } } } return } func Request(a, file string, f func(*UDPConn, *PrivateKey)) { if k, e := LoadPrivateKey(file); e == nil { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() SendKey(conn, k.PublicKey, func() { f(conn, k) }) } } } } func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) { return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l) } func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) { var b bytes.Buffer if e := gob.NewEncoder(&b).Encode(k); e == nil { if _, e = c.Write(b.Bytes()); e == nil { f() } } } whispered secrets http://slides.games-with-brains.net/57
  • 58. package main import "crypto/rsa" import "crypto/rand" import "crypto/sha1" import "crypto/x509" import "bytes" import "encoding/gob" import "encoding/pem" import “io/ioutil" import . "fmt" import . "net" func main() { Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) { if m, e := ReadStream(c); e == nil { if m, e := Decrypt(k, m, []byte("served")); e == nil { Println(string(m)) } } }) } func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) { if file, e := ioutil.ReadFile(file); e == nil { if block, _ := pem.Decode(file); block != nil { if block.Type == "RSA PRIVATE KEY" { r, e = x509.ParsePKCS1PrivateKey(block.Bytes) } } } return } func Request(a, file string, f func(*UDPConn, *PrivateKey)) { if k, e := LoadPrivateKey(file); e == nil { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() SendKey(conn, k.PublicKey, func() { f(conn, k) }) } } } } func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) { return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l) } func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) { var b bytes.Buffer if e := gob.NewEncoder(&b).Encode(k); e == nil { if _, e = c.Write(b.Bytes()); e == nil { f() } } } whispered secrets http://slides.games-with-brains.net/58
  • 59. package main import "crypto/rsa" import "crypto/rand" import "crypto/sha1" import "crypto/x509" import "bytes" import "encoding/gob" import "encoding/pem" import “io/ioutil" import . "fmt" import . "net" func main() { Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) { if m, e := ReadStream(c); e == nil { if m, e := Decrypt(k, m, []byte("served")); e == nil { Println(string(m)) } } }) } func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) { if file, e := ioutil.ReadFile(file); e == nil { if block, _ := pem.Decode(file); block != nil { if block.Type == "RSA PRIVATE KEY" { r, e = x509.ParsePKCS1PrivateKey(block.Bytes) } } } return } func Request(a, file string, f func(*UDPConn, *PrivateKey)) { if k, e := LoadPrivateKey(file); e == nil { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() SendKey(conn, k.PublicKey, func() { f(conn, k) }) } } } } func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) { return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l) } func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) { var b bytes.Buffer if e := gob.NewEncoder(&b).Encode(k); e == nil { if _, e = c.Write(b.Bytes()); e == nil { f() } } } whispered secrets http://slides.games-with-brains.net/59
  • 60. aes + rsa —> hybrid crypto 60
  • 61. aes + hmac —> signature 61
  • 62. crypto + signature —> trust 62
  • 64. package main import . "bytes" import "crypto/hmac" import "crypto/rsa" import "crypto/sha256" import "encoding/base64" import "encoding/gob" import "net" func main() { HELLO_WORLD := []byte("Hello World") RSA_LABEL := []byte("served") SIGNING_KEY := []byte("signature") Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) { var key rsa.PublicKey if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil { if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil { m = append(Sign(HELLO_WORLD, SIGNING_KEY), m) c.WriteToUDP(m, a) } } return }) } func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) { return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l) } func Sign(message string, key []byte) string { h := hmac.New(sha256.New, key) h.Write([]byte(message)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } whispered secrets http://slides.games-with-brains.net/64
  • 65. package main import . "bytes" import "crypto/hmac" import "crypto/rsa" import "crypto/sha256" import "encoding/base64" import "encoding/gob" import "net" func main() { HELLO_WORLD := []byte("Hello World") RSA_LABEL := []byte("served") SIGNING_KEY := []byte("signature") Serve(":1025", func(c *net.UDPConn, a *net.UDPAddr, b []byte) { var key rsa.PublicKey if e := gob.NewDecoder(NewBuffer(b)).Decode(&key); e == nil { if m, e := Encrypt(&key, HELLO_WORLD, RSA_LABEL); e == nil { m = append(Sign(HELLO_WORLD, SIGNING_KEY), m) c.WriteToUDP(m, a) } } return }) } func Encrypt(key *rsa.PublicKey, m, l []byte) ([]byte, error) { return rsa.EncryptOAEP(sha1.New(), rand.Reader, key, m, l) } func Sign(message string, key []byte) string { h := hmac.New(sha256.New, key) h.Write([]byte(message)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } func Serve(a string, f func(*UDPConn, *UDPAddr, []byte)) { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := ListenUDP("udp", address); e == nil { for b := make([]byte, 1024); ; b = make([]byte, 1024) { if n, client, e := conn.ReadFromUDP(b); e == nil { go f(conn, client, b[:n]) } } } } return } whispered secrets http://slides.games-with-brains.net/65
  • 67. package main import "crypto/hmac" import "crypto/rsa" import "crypto/rand" import "crypto/sha1" import "crypto/sha256" import "crypto/x509" import "bytes" import "encoding/base64" import "encoding/gob" import "encoding/pem" import “io/ioutil" import . "fmt" import . "net" func main() { Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) { if m, e := ReadStream(c); e == nil { if m, e := Decrypt(k, m[44:], []byte("served")); e == nil { s, _ := base64.URLEncoding.DecodeString(string(m[:44))) v := hmac.Equal(s, Sign(m, "signature")) Print(string(m), "[valid:", v,"]”) } } }) } func Sign(message string, key []byte) string { h := hmac.New(sha256.New, key) h.Write([]byte(message)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) { var b bytes.Buffer if e := gob.NewEncoder(&b).Encode(k); e == nil { if _, e = c.Write(b.Bytes()); e == nil { f() } } } func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) { if file, e := ioutil.ReadFile(file); e == nil { if block, _ := pem.Decode(file); block != nil { if block.Type == "RSA PRIVATE KEY" { r, e = x509.ParsePKCS1PrivateKey(block.Bytes) } } } return } func Request(a, file string, f func(*UDPConn, *PrivateKey)) { if k, e := LoadPrivateKey(file); e == nil { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() SendKey(conn, k.PublicKey, func() { f(conn, k) }) } } } } func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) { return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l) } whispered secrets http://slides.games-with-brains.net/67
  • 68. package main import "crypto/hmac" import "crypto/rsa" import "crypto/rand" import "crypto/sha1" import "crypto/sha256" import "crypto/x509" import "bytes" import "encoding/base64" import "encoding/gob" import "encoding/pem" import “io/ioutil" import . "fmt" import . "net" func main() { Request(":1025", "ckey", func(c *net.UDPConn, k *rsa.PrivateKey) { if m, e := ReadStream(c); e == nil { if m, e := Decrypt(k, m[44:], []byte("served")); e == nil { s, _ := base64.URLEncoding.DecodeString(string(m[:44))) v := hmac.Equal(s, Sign(m, "signature")) Print(string(m), "[valid:", v,"]”) } } }) } func Sign(message string, key []byte) string { h := hmac.New(sha256.New, key) h.Write([]byte(message)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } func SendKey(c *net.UDPConn, k rsa.PublicKey, f func()) { var b bytes.Buffer if e := gob.NewEncoder(&b).Encode(k); e == nil { if _, e = c.Write(b.Bytes()); e == nil { f() } } } func LoadPrivateKey(file string) (r *rsa.PrivateKey, e error) { if file, e := ioutil.ReadFile(file); e == nil { if block, _ := pem.Decode(file); block != nil { if block.Type == "RSA PRIVATE KEY" { r, e = x509.ParsePKCS1PrivateKey(block.Bytes) } } } return } func Request(a, file string, f func(*UDPConn, *PrivateKey)) { if k, e := LoadPrivateKey(file); e == nil { if address, e := ResolveUDPAddr("udp", a); e == nil { if conn, e := DialUDP("udp", nil, address); e == nil { defer conn.Close() SendKey(conn, k.PublicKey, func() { f(conn, k) }) } } } } func Decrypt(key *rsa.PrivateKey, m, l []byte) ([]byte, error) { return rsa.DecryptOAEP(sha1.New(), rand.Reader, key, m, l) } whispered secrets http://slides.games-with-brains.net/68
  • 69. encrypt all passwords • accept unicode to expand the symbol space • hash every new password before it’s submitted • always use a cryptograpically secure hash (HMAC) • and a fresh HMAC key for each password (which you must store) • salt the resulting hash when you receive it (and store the salt) • then hash again before storing in your database 69
  • 70. require multi-factor authentication • have the user submit their password over a secure channel • then send them a confirmation code out-of-band • that’s an agreed trust anchor acting as a shared secret • the confirmation code should be big enough to generate a HMAC • and only the HMAC should be submitted • now you have two secure channels based on shared secrets 70
  • 71. encrypt all storage • secured transport is useless without secured data stores • encrypt all sensitive fields - that probably means all fields • and store HMACs for desired search terms • otherwise your black box is secure but unsearchable • make sure you use different roles for reading, writing and searching • that’s right, your datastore is also a set of secure streams 71
  • 73. anchor trust internally • establish a private certificate authority • assign fine-grained roles to different components • audit requirements, code, operations, security logs • never deploy without a credible security audit • and make those deployments immutable • security audits best done by third parties with an attacker mentality 73