Secure txscalacsharp

35
Álvaro Rodríguez @alvrod PayTrue

description

 

Transcript of Secure txscalacsharp

Page 1: Secure txscalacsharp

Álvaro Rodríguez

@alvrod

PayTrue

Page 2: Secure txscalacsharp

Características generales de C#

Ejemplos comparados

Observaciones

Page 3: Secure txscalacsharp

var zero = 0;var numbers = new[] {1, 2, 3, 4};numbers.Select(x => x / zero).ToList();

Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.at Test.Application.<>c__DisplayClass3.<Main>b__2(Int32 x) in F:\Visual Studio

Projects\ScalaVsCs\Program.cs:line 21at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)at Test.Application.Main() in F:\Visual Studio Projects\ScalaVsCs\Program.cs:line 21

wat

Page 4: Secure txscalacsharp

Scala

C#

def upperCase(args: Array[String]) { val res = for (a <- args) yield a.toUpperCaseprintln("Arguments: " + res.mkString)

}…upperCase(Array ("a", "b", "c"))

public static void UpperCase(string[] args) {var res = from arg in args select arg.ToUpperInvariant();Console.Out.WriteLine("Arguments: {0}", String.Join("", res));

}…UpperCase(new []{"a", "b", "c"});

Page 5: Secure txscalacsharp

Scala

C#

def upperCase(args: Array[String]) { val res = for (a <- args) yield a.toUpperCaseprintln("Arguments: " + res.mkString)

}…upperCase(Array ("a", "b", "c"))

public static IEnumerable<string> UpperCaseYield(string[] args) {foreach (var arg in args) {yield return arg.ToUpperInvariant();

}}

Page 6: Secure txscalacsharp

object implicits {implicit def arrayWrapper[A : ClassTag](x: Array[A]) = new { def sort(p: (A, A) => Boolean) = {

util.Sorting.stableSort(x, p); x }

} }

import implicits._ …

Scala

val numbers = Array(2, 3, 1, 4) numbers.sort((x: Int, y: Int) => x < y))

Page 7: Secure txscalacsharp

C#public static class implicits {

public static IList<T> MySort<T>(this IList<T> list, Func<T, T, int> func) where T : class {

var temp = list.ToArray();Array.Sort(temp, (x, y) => func(x, y));return temp;

}}

var objects = new[] {"a", "b", "c"}; objects.MySort(String.CompareOrdinal);

Page 8: Secure txscalacsharp

Pattern matching

Inmutabilidad

Inferencia de tipos

Locuacidad (DSL)

Expressions everywhere

Option > null, Nullable<T>

trait >>>> interface

case class > auto-properties

macros / compiler-as-a-service > roslyn

Page 9: Secure txscalacsharp

Automatic Resource Management Scala, a través de librerías

C#, magia en el compilador

Debatible Madurez

dynamic

async / await

Código nativo

Xamarin

Page 10: Secure txscalacsharp

JVM

Scala

CLR

C# tiene bastantes cosas, aunque a veces la sintaxis no es la mejor

F#

“Scala feels closer to Java than F# to C#”

Java-----C#-------Scala-------------------F#

Page 11: Secure txscalacsharp

let zero = 0let numbers = [| 1; 2; 3 |]Seq.map(fun x -> x / zero) numbers |> Seq.length

System.DivideByZeroException: Attempted to divide by zero.

at [email protected](Int32 x) <- watat [email protected](b& )at Microsoft.FSharp.Collections.IEnumerator.MapEnumerator`1.System-Collections-IEnumerator-

MoveNext()at Microsoft.FSharp.Collections.SeqModule.Length[T](IEnumerable`1 source)at <StartupCode$FSI_0002>.$FSI_0002.main@()at main@dm()

Stopped due to error

Page 12: Secure txscalacsharp

Una breve introducción a la industria de tarjetas de crédito

Por qué el proyecto vale la pena

Visión funcional de la aplicación

Page 13: Secure txscalacsharp

MasterCard, VISA, American Express

Esquema descentralizado de cobertura mundial

Iniciativas para nuevos negocios, control de fraude Chip & PIN (EMV), “Verified By Visa”,

etc.

PCI Council PCI DSS

Data Security Standard

Aplicable a ambientes productivos

PA DSS

Aplicable a aplicaciones de pagos

Page 14: Secure txscalacsharp
Page 15: Secure txscalacsharp

Estándares de seguridad para proteger información sensible de tarjetas y prevenir fraude

Obligatorios para proveedores de servicio, comercios, etc.

Apuntan a impedir el acceso pero también a desvalorizar la información

Page 16: Secure txscalacsharp
Page 17: Secure txscalacsharp

Nº de tarjeta, tracks, PIN, en claro, “por todos lados”CRM, contabilidad, facturación, etc. etc.

Sistemas no preparados para cumplir con la norma PCI DSS

Enorme costo de adaptación

La norma en sí es cara y difícil de cumplir

Page 18: Secure txscalacsharp

El estándar tiene más de 260 requisitos individuales, afectando desde políticas de RRHH hasta el control de qué servicios se ejecutan en cada computadora dentro del “ambiente de tarjetas PCI”

Análisis GAP: 2 meses

Proyecto PCI: 7 meses

Certificación / ajustes: 2 meses

~2 millones U$S

+

200.000 – 500.000+ U$S / añoen auditorías

Page 19: Secure txscalacsharp

Cada módulo de software que deba certificarse tiene un sobrecosto enorme por los requisitos técnicos.

Documentación

Detalles de logging, seguridad, estándares

Evidencia de procesos de desarrollo seguro, etc.

Criptografía -> gestión de claves

Page 20: Secure txscalacsharp
Page 21: Secure txscalacsharp

PCI aplica sólo a “sistemas que almacenan, procesan o transmiten el nº de tarjeta”

La forma más fácil de “certificar PCI” entonces es evitar almacenar, procesar o transmitir el nº de tarjeta

SecureTX es PA-DSS, el resto queda fuera de la norma

Page 22: Secure txscalacsharp

Estrategia de reducción del alcance a través de tokenización

def tokenize(card:String): String

5588 3201 2345 6789

->

1000 0000 4365 6789

Desarrollo de middleware tokenizador “Secure TX”

Page 23: Secure txscalacsharp

Diseño con Akka

Implementación

Observaciones. Discusión.

Page 24: Secure txscalacsharp

“Tokenizer” es un servicio web aparte

“SecureTX switch”es la aplicación que estamos discutiendo

“Authorizer / switch”podría ser un procesador de pagos cualquiera

El esquema de la derecha es minimal, se dan escenarios más complejos

Transaction

storage

Authorizer /

switch

SecureTX

switch

SecureTX

tokenizer

Encrypted card

storage

TX

1

2

34

5

Page 25: Secure txscalacsharp

Producto caja, cerrado

Distintos canales

TCP

JMS

Distintos formatos

ISO 8583 en distintos sabores

ASCII largo fijo

Distintos flujos

Camino crítico transaccional

Estabilidad

Performance

Page 26: Secure txscalacsharp

Akka

Librería y runtime para desarrollar aplicaciones para la JVM

Altamente concurrentes

Distribuidas

Con tolerancia a fallas

Orientadas a eventos asincrónicos

Modelo de actores

Cada actor tiene un mailbox de eventos: mensajes que procesa secuencialmente

Modelo de ejecución simplificado, fácil de entender y evitar problemas típicos de concurrencia

Modelo de supervisión para tolerancia a fallas

Meta-actores (p.e. para distribución de carga)

Page 27: Secure txscalacsharp

Librería para integración de mensajes

“Todos con todos” de canales x formatos

Canales: JMS, Archivos, HTTP, … …

Formatos: Largo fijo, CSV, XML, JSON, etc.

Muy configurable mediante Spring

Rutas, endpoints, etc.

EAI patterns en código o XML

Akka – Camel integra ambas librerías

Page 28: Secure txscalacsharp

SecureTX "Switch"

Switch

Tokenizer

PaymentProcessorSender

PaymentProcessorReceiver

ManagementReceiver

ManagementSender

TcpServerA

TcpServerB

TcpClientD

HSM

Tokenizer Service

Authorizer

HSM Server

POS Network

E Gateway

VISA

MasterCard

TcpClientE

Page 29: Secure txscalacsharp

TCP, HSM – Akka.IO 2.2 en Scala

Precisamos full-duplex asincrónico, y Camel es one-way o request-reply

Binario + ISO8583 o “ASCII largo fijo” configurable

Tokenizer, PaymentProcessor, Management

Camel

En principio:

Tokenizer por HTTP4

PaymentProcessor, Management por JMS

Pero parte de la gracia de Camel es que esto es muy configurable

Page 30: Secure txscalacsharp

class Tokenizer extends Actor with Producer with akka.actor.ActorLogging {

val config = SwApp.appConfigContext.getBean(self.path.name).asInstanceOf[TokenizerBean]

val contextHeader = "TOKENIZER_CONTEXT"

val cardIdResource = "cardid"

val cardNumberResource = "cardnumber"

def endpointUri: String = s"http4://${config.host}:${config.port}"

override def transformOutgoingMessage(msg: Any) = msg match {

case TokenizeRequest(cardNumber, senderContext) => CreateCamelMessage(cardIdResource, cardNumber, senderContext)

case OpenCardRequest(token, senderContext) => CreateCamelMessage(cardNumberResource, token, senderContext)

}

private def CreateCamelMessage(resource:String, data:String, senderContext:Any) = {

val headers = Map(

Exchange.HTTP_URI -> s"$endpointUri/$resource/$data",

Exchange.HTTP_METHOD -> "GET",

contextHeader -> senderContext

)

CamelMessage("", headers)

}

override def transformResponse(msg: Any) = msg match {

case msg: CamelMessage => msg.headerAs[String](Exchange.HTTP_URI) match {

case Success(cardId) if cardId.contains(cardIdResource) => TokenizeResponse(msg.bodyAs[String], msg.headers(contextHeader))

case Success(cardNumber) if cardNumber.contains(cardNumberResource) => OpenCardResponse(msg.bodyAs[String], msg.headers(contextHeader))

case Success(other) => log.error("Unexpected response {} from Tokenizer", other)

case Failure(e) => log.error(e, "Error received from Tokenizer")

}

case akka.actor.Status.Failure(e) => log.error(e, "Error received from Tokenizer")

}

}

Page 31: Secure txscalacsharp

2200 LOC Scala

promedio 100 por archivo

1000 LOC Java (HSM)

promedio 145 por archivo

.jar 300 kb

lib 22 mb

“If I have seen further it is by standing on the shoulders of giants”

Page 32: Secure txscalacsharp

akka-testkit

ScalaTest

TeamCity no sabe ejecutar tests de Scala

http://youtrack.jetbrains.com/issue/TW-29678

Page 33: Secure txscalacsharp

JMeter

En condiciones preliminares e imperfectas

Ambiente local + Oracle de desarrollo

Flujo simplificado

“Enviando” las transacciones a log por Camel (sin JMS)

Todo con la misma tarjeta

~100 tps

Page 34: Secure txscalacsharp

A través del “ManagementReceiver” podemos dinámicamente configurar, bajar, reiniciar canales.

Trivial de hacer con Akka

Metrics de @coda

Además enviamos status a través del "ManagementSender"

Page 35: Secure txscalacsharp