Secure txscalacsharp
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
422
On Slideshare
420
From Embeds
2
Number of Embeds
1

Actions

Shares
Downloads
1
Comments
0
Likes
0

Embeds 2

https://twitter.com 2

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Álvaro Rodríguez @alvrod PayTrue
  • 2. Características generales de C# Ejemplos comparados Observaciones
  • 3. 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 ProjectsScalaVsCsProgram.cs:line 21 at 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 ProjectsScalaVsCsProgram.cs:line 21 wat
  • 4.  Scala  C# def upperCase(args: Array[String]) { val res = for (a <- args) yield a.toUpperCase println("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"});
  • 5.  Scala  C# def upperCase(args: Array[String]) { val res = for (a <- args) yield a.toUpperCase println("Arguments: " + res.mkString) } … upperCase(Array ("a", "b", "c")) public static IEnumerable<string> UpperCaseYield(string[] args) { foreach (var arg in args) { yield return arg.ToUpperInvariant(); } }
  • 6. 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))
  • 7.  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);
  • 8.  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
  • 9.  Automatic Resource Management  Scala, a través de librerías  C#, magia en el compilador  Debatible  Madurez  dynamic  async / await  Código nativo  Xamarin
  • 10.  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#
  • 11. let zero = 0 let numbers = [| 1; 2; 3 |] Seq.map(fun x -> x / zero) numbers |> Seq.length System.DivideByZeroException: Attempted to divide by zero. at FSI_0002.it@7-1.Invoke(Int32 x) <- wat at Microsoft.FSharp.Collections.IEnumerator.map@116.DoMoveNext(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
  • 12. 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
  • 13.  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
  • 14. 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
  • 15.  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
  • 16. 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ño en auditorías
  • 17. 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
  • 18. 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
  • 19. 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”
  • 20. Diseño con Akka Implementación Observaciones. Discusión.
  • 21.  “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
  • 22.  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
  • 23.  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)
  • 24.  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
  • 25. SecureTX "Switch" Switch Tokenizer PaymentProcessorSender PaymentProcessorReceiver ManagementReceiver ManagementSender TcpServerA TcpServerB TcpClientD HSM Tokenizer Service Authorizer HSM Server POS Network E Gateway VISA MasterCard TcpClientE
  • 26.  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
  • 27. 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") } }
  • 28.  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”
  • 29.  akka-testkit  ScalaTest  TeamCity no sabe ejecutar tests de Scala  http://youtrack.jetbrains.com/issue/TW- 29678
  • 30.  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
  • 31.  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"