{"version":3,"sources":["webpack:///./src/posts/2016-03-05-HTTP-Public-Key-Pinning-with-Spring-Security.md"],"names":["_frontmatter","layoutProps","MDXLayout","DefaultLayout","MDXContent","components","props","mdxType","href","target","parentName","isMDXComponent"],"mappings":"+QAMO,IAAMA,EAAe,GAOtBC,EAAc,CAClBD,gBAEIE,EAAYC,IACH,SAASC,EAAT,GAGZ,IAFDC,EAEC,EAFDA,WACGC,E,oIACF,mBACD,OAAO,YAACJ,EAAD,iBAAeD,EAAiBK,EAAhC,CAAuCD,WAAYA,EAAYE,QAAQ,cAG5E,uDACA,0OACuB,iBAAGC,KAAK,qCAAqCC,OAAO,UAApD,YADvB,2SAG6D,iBAAGD,KAAK,mDAAmDC,OAAO,UAAlE,QAH7D,gBAIA,6CACA,0WAEA,sBAAQC,WAAW,KAAnB,YAFA,0BAEuE,iBAAGF,KAAK,wEAAwEC,OAAO,UAAvF,gBAFvE,qGAGA,sRAEA,uHACA,uBAAK,kCAAMC,WAAW,OAAU,CAC5B,UAAa,kBADZ,uPASL,0CAAyB,sBAAQA,WAAW,KAAnB,mBAAzB,mHACe,sBAAQA,WAAW,KAAnB,6DADf,iFAEyB,sBAAQA,WAAW,KAAnB,6DAFzB,+BAGF,sBAAQA,WAAW,KAAnB,mBAHE,mMAIsE,sBAAQA,WAAW,KAAnB,qBAJtE,2BAKO,sBAAQA,WAAW,KAAI,0BAAYA,WAAW,UAAvB,qDAL9B,sDAMA,4EACA,mEACA,4NAGA,yCACA,uBAAK,kCAAMA,WAAW,OAAU,CAC5B,UAAa,kBADZ,gHAIL,kEACA,uBAAK,kCAAMA,WAAW,OAAU,CAC5B,UAAa,kBADZ,mJAIL,4CACA,uBAAK,kCAAMA,WAAW,OAAU,CAC5B,UAAa,kBADZ,gJAIL,mDACA,uBAAK,kCAAMA,WAAW,OAAU,CAC5B,UAAa,kBADZ,qMAIL,qEACA,sBACE,kBAAIA,WAAW,MAAf,sCAA2D,0BAAYA,WAAW,MAAvB,iDAC3D,kBAAIA,WAAW,MAAf,sCAA2D,0BAAYA,WAAW,MAAvB,kDAE7D,qDACA,sCAAqB,sBAAQA,WAAW,KAAnB,aAArB,iDAAoH,0BAAYA,WAAW,KAAvB,oBAApH,sGACwD,sBAAQA,WAAW,KAAnB,sBADxD,gDAC+J,sBAAQA,WAAW,KAAnB,qBAD/J,yCAGA,uBAAK,kCAAMA,WAAW,OAAU,CAC5B,UAAa,kBADZ,wdAcL,uBAAK,kCAAMA,WAAW,OAAU,CAC5B,UAAa,iBADZ,6aAsBTN,EAAWO,gBAAiB","file":"component---src-posts-2016-03-05-http-public-key-pinning-with-spring-security-md-95499d80dbabe8eabe14.js","sourcesContent":["import React from 'react'\n /* @jsx mdx */\nimport { mdx } from '@mdx-js/react';\n/* @jsx mdx */\n\nimport DefaultLayout from \"/opt/build/repo/src/templates/posts.js\";\nexport const _frontmatter = {};\n\nconst makeShortcode = name => function MDXDefaultShortcode(props) {\n console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n return
;\n};\n\nconst layoutProps = {\n _frontmatter\n};\nconst MDXLayout = DefaultLayout;\nexport default function MDXContent({\n components,\n ...props\n}) {\n return{`HTTP Public Key Pinning, or short HPKP, is a security mechanism which allows HTTPS websites to resist impersonation by attackers using mis-issued or otherwise fraudulent certificates.\nThis was standardized in `}{`RFC 7469`}{` and creates a new opportunity for server validation.\nInstead of using static certificate pinning, where public key hashes are hardcoded within an application, we can now use a more dynamic way of providing this public key hashes.\nOne caveat to remember is that HPKP uses a Trust On First Use (`}{`TOFU`}{`) technique.`}
\n{`A list of public key hashes will be served to the client via a special HTTP header by the web server, so clients can store this information for a given period of time.\nOn subsequent connections within previous given period of time, the client expects a certificate containing a public key whose fingerprint is already known via HPKP.\nI `}{`strongly`}{` encourage you to read `}{`this article`}{` by Tim Taubert, where he explains what keys you should pin and what the different tradeoffs are.`}
\n{`Imagine you want to terminate the connection between the client and a malicious server for your main domain and all of your subdomains, but also want to be notified when such events happen.\nIn the next paragraph you can find the implementation details.`}
\n{`The web server needs to send following header to the connecting client with the first response`}
\n{`Public-Key-Pins:\n max-age=5184000;\n pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\";\n pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\";\n report-uri=\"https://example.net/hpkp-report\";\n includeSubdomains\n`}
\n {`By specifying the `}{`Public-Key-Pins`}{` header the client MUST terminate the connection without allowing the user to proceed anyway.\nIn this example, `}{`pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\"`}{` pins the server's public key used in production.\nThe second pin declaration `}{`pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\"`}{` also pins the backup key.\n`}{`max-age=5184000`}{` tells the client to store this information for two month, which is a reasonable time limit according to the IETF RFC.\nThis key pinning is also valid for all subdomains, which is told by the `}{`includeSubdomains`}{` declaration.\nFinally, `}
{`We first need to get a list of public key hashes.\nCurrently the standard only supports the SHA256 hashing algorithm.\nThe following commands will help you extract the Base64 encoded information:`}
\n{`openssl rsa -in my-key-file.key -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64\n`}
\n {`openssl req -in my-signing-request.csr -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64\n`}
\n {`openssl x509 -in my-certificate.crt -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64\n`}
\n {`openssl s_client -servername www.example.com -connect www.example.com:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64\n`}
\n {`For now we will assume we got 2 public keys:`}
\n{`As of version `}{`4.1.0.RC1`}{`, which will be released March 24th 2016, the `}
{`@EnableWebSecurity\npublic class HpkpConfig extends WebSecurityConfigurerAdapter {\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http.httpPublicKeyPinning()\n .addSha256Pins(\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\", \"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\")\n .reportOnly(false)\n .reportUri(\"http://example.net/hpkp-report\")\n .includeSubDomains(true);\n }\n}\n`}
\n {`\n \n\n \n \n \n d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= \n E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g= \n \n \n \n \n`}
\n\n