Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PHP Experience 2016 - [Palestra] Autenticação em APIs

606 views

Published on

Marcelo Milhomem, Technical Lead no Easy Taxi, fez a palestra "Autenticação em APIs", no PHP Experience 2016.

O iMasters PHP Experience 2016 aconteceu nos dias 21 e 22 de Março de 2015, no Hotel Tivoli em São Paulo-SP
http://phpexperience2016.imasters.com.br/

Published in: Education
  • Be the first to comment

  • Be the first to like this

PHP Experience 2016 - [Palestra] Autenticação em APIs

  1. 1. Autenticação em APIs Marcelo Milhomem
  2. 2. Agenda
  3. 3. Agenda • HTTP REST API • Autenticação • SSL / Autoridade Certificadora / Certificados • Aplicação em Mobile
  4. 4. Autenticação x Autorização
  5. 5. 401 vs 403 • 401 Unauthorised - Não autenticado Eu preciso saber quem você é • 403 Forbidden - Não autorizado Eu sei quem você é mas, você não tem direito
  6. 6. Autenticação hoje
  7. 7. HTTP Basic (Usuário e Senha) • Cleartext • Precisa de SSL • Fácil de "crackear" • Usuário preguiçoso (mesma senha / senha fraca) • Mesma senha em vários sistemas
  8. 8. OAuth (Autenticação + Autorização)
  9. 9. Token / JWT 1 { 2 "sub": "1234567890", 3 "name": "John Doe", 4 "admin": true 5 } 1 HMACSHA256( 2 base64UrlEncode(header) + "." + 3 base64UrlEncode(payload), 4 secret) 1 eyJhbGciOiJIUzI1NiIsInR 2 5cCI6IkpXVCJ9. 3 eyJzdWIiOiIxMjM0NTY3ODk 4 wIiwibmFtZSI6IkpvaG4gRG 5 9lIiwiYWRtaW4iOnRydWV9. 6 TJVA95OrM7E2cBab30RMHrH 7 DcEfxjoYZgeFONFh7HgQ
  10. 10. Todos usam SSL
  11. 11. Por que o SSL?
  12. 12. Certificados • Par de chaves assimétricas (Pública e Privada) • Oferece a mesma coisa que o SSL • Autentica o cliente através da assinatura digital • Requer um `round trip` extra
  13. 13. Autoridade Certificadora (CA) • Self signed (todo CA é) • CA intermediário (cadeias de CA) - boa prática para evitar perda total em caso de comprometimento da chave privada • Você é a autoridade :0 dona da verdade • Utilizar CA intermediários como ACL
  14. 14. Show Case
  15. 15. Ingredientes Keystore Certificado do Cliente Certificado do Servidor Keystore CA
  16. 16. Gerar certificado do cliente
  17. 17. Gerar certificado - PHP Gerando par de chaves do cliente 1 /** 2 * Chave privada 3 */ 4 $clientPrivateKey = new Crypt_RSA(); 5 $clientPrivateKey->setPassword($password); 6 $generatedKeyPair = $clientPrivateKey->createKey(); 7 $clientPrivateKey->loadKey($generatedKeyPair['privatekey']); 8 /** 9 * Chave pública 10 */ 11 $clientPublicKey = new Crypt_RSA(); 12 $clientPublicKey->loadKey($generatedKeyPair['publickey']); 13 $clientPublicKey->setPublicKey();
  18. 18. Gerar certificado - PHP Par de chaves do CA 1 /** 2 * Chave privada do CA necessária para assinar 3 */ 4 $privateKeyIntermediateCA = new Crypt_RSA(); 5 $privateKeyIntermediateCA->setPassword('Intermediate CA password'); 6 $privateKeyIntermediateCA->loadKey(file_get_contents($privateCAKeyPath)); 7 /** 8 * Certificado do CA 9 */ 10 $certificateIntermediateCA = new File_X509(); 11 $certificateIntermediateCA->setPrivateKey($privateKeyIntermediateCA); 12 $certificateIntermediateCA->loadX509(file_get_contents($certificateCAKeyPath));
  19. 19. Certificado do Cliente - PHPAssinando o certificado 1 /** 2 * CSR - Requisição de certificado 3 */ 4 $certificateSigningRequest = new File_X509(); 5 $certificateSigningRequest->setDN($certificateIntermediateCA->getDN()); 6 $certificateSigningRequest->setPublicKey((object)$clientPublicKey); 7 $certificateX509 = new File_X509(); 8 $certificateX509->setEndDate('+1 month'); 9 /** 10 * Assinatura do CA 11 */ 12 $clientCertificate = 13 $certificateX509->sign($certificateIntermediateCA, $certificateSigningRequest); 14 /** 15 * Resultado chave privada + certificado do cliente 16 */ 17 echo $clientPrivateKey->getPrivateKey(); 18 echo PHP_EOL; 19 echo $certificateX509->saveX509($clientCertificate);
  20. 20. Certificado do Cliente - Android 1 /** 2 * Certificado do cliente + chave privada empacotados em um arquivo PFX 3 */ 4 KeyStore keyStore = KeyStore.getInstance("PKCS12"); 5 FileInputStream clientCertificateContent = 6 new FileInputStream("/path/to/publicAndPrivateKey.p12"); 7 keyStore.load(clientCertificateContent, "private key password".toCharArray()); 8 KeyManagerFactory keyManagerFactory = 9 KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 10 keyManagerFactory.init(keyStore, "private key password".toCharArray());
  21. 21. Embarcar CA 1 -----BEGIN CERTIFICATE----- 2 MIIDnzCCAwigAwIBAgIJAJZTKp0w82kyMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD 3 VQQGEwJCUjETMBEGA1UECBQKU8OjbyBQYXVsbzETMBEGA1UEBxQKU8OjbyBQYXVs 4 bzERMA8GA1UEChMIRWFzeVRheGkxETAPBgNVBAsTCEVhc3lUYXhpMQswCQYDVQQD 5 EwJFVDEmMCQGCSqGSIb3DQEJARYXY29udGF0b0BlYXN5dGF4aS5jb20uYnIwHhcN 6 MTYwMTE4MTYwNDQ2WhcNMzYwMTEzMTYwNDQ2WjCBkjELMAkGA1UEBhMCQlIxEzAR 7 BgNVBAgUClPDo28gUGF1bG8xEzARBgNVBAcUClPDo28gUGF1bG8xETAPBgNVBAoT 8 CEVhc3lUYXhpMREwDwYDVQQLEwhFYXN5VGF4aTELMAkGA1UEAxMCRVQxJjAkBgkq 9 hkiG9w0BCQEWF2NvbnRhdG9AZWFzeXRheGkuY29tLmJyMIGfMA0GCSqGSIb3DQEB 10 AQUAA4GNADCBiQKBgQDTny6B8fbG1UXEtMYYFKfODKduzYTovLIUzXKFrX9wHEsC 11 lTOLqtvKsvkLkjXsC3R/HedWoRbFXJbaaw723csPlxrxuBqfkNBJB25ihccwVWbP 12 WpEaDluL2btsBdW2uuDshpXk2z6Gf5xcePnmf24iWpvJs1uBJWkEGRR2TzEi8wID 13 AQABo4H6MIH3MB0GA1UdDgQWBBRMm/EjlWrvxXTtUmotq+kwN52u3zCBxwYDVR0j 14 BIG/MIG8gBRMm/EjlWrvxXTtUmotq+kwN52u36GBmKSBlTCBkjELMAkGA1UEBhMC 15 QlIxEzARBgNVBAgUClPDo28gUGF1bG8xEzARBgNVBAcUClPDo28gUGF1bG8xETAP 16 BgNVBAoTCEVhc3lUYXhpMREwDwYDVQQLEwhFYXN5VGF4aTELMAkGA1UEAxMCRVQx 17 JjAkBgkqhkiG9w0BCQEWF2NvbnRhdG9AZWFzeXRheGkuY29tLmJyggkAllMqnTDz 18 aTIwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAEcW5DO0ODdWd0kZzU 19 6eSg8ckDPImveTiKpFU5a96WxlVmwU8IlwAZ695w6ciIwDjys6BUNUBayTczhJbO 20 83Ykrt+b62+ksqKKFrCcba10R8QSjhYZSy7Yv08m/6+OiP+rUb2Jg4zVdAPhaaVn 21 lb1Nff1EgOdWIdjTKpPzHRjY4g== 22 -----END CERTIFICATE----- Autoridade Certificadora Aplicativo Mobile
  22. 22. Requisição OkHttp - Android 1 OkHttpClient client = new OkHttpClient(); 2 client.setSslSocketFactory(sslContext.getSocketFactory()); 3 client.newCall(new Request.Builder() 4 .url("https://easytaxi.com.br") 5 .build() 6 ).execute();
  23. 23. Adicionando Cabeçalhos 1 GET /passenger/56edfd08756f458a6f0041ad HTTP/1.1 2 Host: api.easytaxi.com.br 3 User-Agent: curl/7.43.0 4 X-SSL: 1 5 X-SSL-Client-Verify: 0 6 X-SSL-Client-SHA1: "a01b894d12579d88efce97d27107f380b05f5968" 7 X-SSL-Client-CN: "56edfd08756f458a6f0041ad" 8 X-SSL-Issuer: "/C=BR/OU=EasyTaxi/emailAddress=contato@easytaxi.com.br” 9 X-SSL-Client-Not-Before: "120101100030Z" 10 X-SSL-Client-Not-After: "160101100030Z" 11 Accept: */*
  24. 24. Use Cases
  25. 25. Validade • Todo certificado tem validade • Demonstração • Teste gratuito temporário • Revalidação de login
  26. 26. Grupos e Cadeias • Você pode criar vários CAs intermediários • Criar intermediário e assinar os usuários do grupo com ele • Revogar um intermediário e todos certificados abaixo dele • Intermediários também possuem validade
  27. 27. Integridade • Benefício da autenticação mútua (2WAY)
  28. 28. Assinatura digital • Não repúdio - Garantia da que o portador assinou • Assinar documentos digitalmente • Certificado digital
  29. 29. Offload
  30. 30. Descentralizado • Servidores conseguem validar o certificado offline • Precisam apenas compartilhar as chaves do CA • Ideal para microserviços
  31. 31. Emissão on-demand • Emissão de certificados dinamicamente • Let’s Encrypt faz isso para certificado de servidores • Crie sua PKI para emitir certificados para clientes
  32. 32. Autorização Simples - 403 1 #GET /passenger/56edfd08756f458a6f0041ad HTTP/1.1 2 $uri = current(explode('?', getenv('REQUEST_URI'))); 3 preg_match('#[a-zA-Z0-9-]+(/)?$#', $uri, $matches); 4 $passengerId = $matches[0]; 5 if ($request->headers->get('X-SSL-Client-CN') != $passengerId) { 6 return new Response('Forbidden', 403); 7 }
  33. 33. Gerar certificado - PHPAssinando o certificado 1 /** 2 * CSR - Requisição de certificado 3 */ 4 $certificateSigningRequest = new File_X509(); 5 $certificateSigningRequest->setDN($certificateIntermediateCA->getDN()); 6 $certificateSigningRequest->setDNProp('uniqueidentifier', 'my unique ID'); 7 $certificateSigningRequest->setPublicKey((object)$clientPublicKey); 8 $certificateX509 = new File_X509(); 9 $certificateX509->setEndDate('+1 month'); 10 /** 11 * Assinatura do CA 12 */ 13 $clientCertificate = 14 $certificateX509->sign($certificateIntermediateCA, $certificateSigningRequest);
  34. 34. Por que ninguém ta usando isso?
  35. 35. Perguntas? Vamos manter contato! https://legacy.joind.in/17491 https://gist.github.com/milhomem

×