{"id":18457966,"url":"https://github.com/alokkusingh/x509-authentication","last_synced_at":"2025-04-23T12:19:03.954Z","repository":{"id":95088524,"uuid":"278845206","full_name":"alokkusingh/x509-authentication","owner":"alokkusingh","description":"Spring Security X.509 Certificate Based Authentication - Mutual Autnetication","archived":false,"fork":false,"pushed_at":"2022-04-19T12:05:15.000Z","size":341,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-23T12:18:50.105Z","etag":null,"topics":["spring-security","x509-based-authentication","x509-mutual-authentication","x509-parser","x509certificates"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alokkusingh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-11T11:09:11.000Z","updated_at":"2024-07-08T17:42:08.000Z","dependencies_parsed_at":"2023-03-05T07:00:16.073Z","dependency_job_id":null,"html_url":"https://github.com/alokkusingh/x509-authentication","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alokkusingh%2Fx509-authentication","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alokkusingh%2Fx509-authentication/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alokkusingh%2Fx509-authentication/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alokkusingh%2Fx509-authentication/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alokkusingh","download_url":"https://codeload.github.com/alokkusingh/x509-authentication/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250430602,"owners_count":21429324,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["spring-security","x509-based-authentication","x509-mutual-authentication","x509-parser","x509certificates"],"created_at":"2024-11-06T08:16:16.751Z","updated_at":"2025-04-23T12:19:03.936Z","avatar_url":"https://github.com/alokkusingh.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/alokkusingh/x509-authentication.svg?branch=master)](https://travis-ci.org/github/alokkusingh/x509-authentication)\n[![GitHub issues](https://img.shields.io/github/issues/alokkusingh/x509-authentication.svg)](https://github.com/alokkusingh/x509-authentication/issues)\n[![GitHub issues closed](https://img.shields.io/github/issues-closed-raw/alokkusingh/x509-authentication.svg?maxAge=2592000)](https://github.com/alokkusingh/x509-authentication/issues?q=is%3Aissue+is%3Aclosed)\n\n# x509-authentication\nSpring Security X.509 Certificate Based Authentication\n\nInstead of Password based challenge, the server identifies client using their certificate.\n\nTable of Contents\n=================\n\n   * [Certificate Generation and Usage](#certificate-generation-and-usage)\n   * [Contents in Key Store and Truststore](#contents-in-key-store-and-truststore)\n   * [TCP Dump and Analysis](#tcp-dump-and-analysis)\n\nCreated by [Alok Singh](https://github.com/alokkusingh)\n\n## Certificate Generation and Usage\n\n1) `Root Certificate`\n\n\t\topenssl req -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout rootCA_Alok.key -out rootCA_Alok.crt\n\t\t\n\t\tPwd: changeit\n\t\tgenerates: \n\t\t\trootCA_Alok.key\n\t\t\trootCA_Alok.crt\n\n2) `Server Side Certificate` - this will be used by Spring Boot Server\n\t\n\t2.1) Generate Server Side Certificate\n\t\n\t\topenssl req -new -newkey rsa:4096 -keyout localhost.key -out localhost.csr\n\n\t\tCountry Name (2 letter code) []:IN\n\t\tState or Province Name (full name) []:KA\n\t\tLocality Name (eg, city) []:BLR\n\t\tOrganization Name (eg, company) []:Home\n\t\tOrganizational Unit Name (eg, section) []:Abc\n\t\tCommon Name (eg, fully qualified host name) []:localhost\n\t\tEmail Address []:alok.ku.singh@gmail.com\n\n\t\tPlease enter the following 'extra' attributes\n\t\tto be sent with your certificate request\n\t\tA challenge password []:\n\n\t\tgenerates:\n\t\t\tlocalhost.key\n\t\t\tlocalhost.csr\n\n\t2.2) Sign Cert with Alok Root:\n\t\t\n\t\tvim localhost.ext\n\t\tauthorityKeyIdentifier=keyid,issuer\n\t\tbasicConstraints=CA:FALSE\n\t\tsubjectAltName = @alt_names\n\t\t[alt_names]\n\t\tDNS.1 = localhost\n\n\t\topenssl x509 -req -CA rootCA_Alok.crt -CAkey rootCA_Alok.key -in localhost.csr -out localhost.crt -days 365 -CAcreateserial -extfile localhost.ext\n\t\tgenerates:\n\t\t\trootCA_Alok.srl\n\t\t\tlocalhost.crt\n\n\n\t2.3) Import to Keystore:\n\n\t\t1st) Add the loaclhost.key and loaclhost.crt in single PKCS 12 bundle:\n\t\t\t\n\t\t\topenssl pkcs12 -export -out localhost.p12 -name \"localhost\" -inkey localhost.key -in localhost.crt\n\t\t\tPwd: \u003cpassword and remeber for furture use\u003e\n\t\t\tgenerates:\n\t\t\t\tlocalhost.p12\n\n\t\t2nd) Import PKCS bundle to JKS\n\t\t\t\n\t\t\tkeytool -importkeystore -srckeystore localhost.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS\n\t\t\tPwd: \u003cpassword and remeber for furture use\u003e\n\t\t\tgenerates:\n\t\t\t\tkeystore.jks\n\n\n3) `Import Root CA cert to browser as Authority certificate` - so that browser trust cert which is signed using this Root Cert (no risk warning will be shown in the browser)\n\n\t\tAn exemplary installation of our certificate authority for Mozilla Firefox would look like follows:\n\n\t\tType about:preferences in the address bar\n\t\tOpen Advanced -\u003e Certificates -\u003e View Certificates -\u003e Authorities\n\t\tClick on Import\n\t\tSelect rootCA_Alok.crt file and click OK\n\t\tChoose “Trust this CA to identify websites” and click OK\n\n\n4) `Create Trust Store and Import Root CA cert which is used to sign Client Certificate` - so that server trusts certificate signed using the same Root CA certificate:\n\n\t\tkeytool -import -trustcacerts -noprompt -alias ca -ext san=dns:localhost,ip:127.0.0.1 -file rootCA_Alok.crt -keystore truststore.jks\n\t\tPwd: \u003cpassword and remeber for furture use\u003e\n\t\tgenerates: truststore.jks\n\n\n5) `Create Client Certificate for Alok and Sign using RootCA_Alok so that server trusts`\n\n\tServer Says: I dont trust \"Client Alok\" (since Alok certificate is not addded in JKS) but I do trust \"Root CA Alok\" and he trusts you so do I.\n\t\n\t5.1) Generate Client Key and CSR\n\t\n\t\topenssl req -new -newkey rsa:4096 -nodes -keyout clientAlok.key -out clientAlok.csr\n\t\tPwd: no password\n\t\tgenerates:\n\t\t\tclientAlok.key\n\t\t\tclientAlok.csr\n\n\t5.2) Sign cert for Alok with RootCA_Alok:\n\t\t\n\t\topenssl x509 -req -CA rootCA_Alok.crt -CAkey rootCA_Alok.key -in clientAlok.csr -out clientAlok.crt -days 365 -CAcreateserial\n\t\tgenerates: \n\t\t\tclientAlok.crt\n\n\t5.3) Import cert to PKCS Bundle:\n\t\t\n\t\topenssl pkcs12 -export -out clientAlok.p12 -name \"clientAlok\" -inkey clientAlok.key -in clientAlok.crt\n\t\tPwd: No password\n\t\tgenerates:\n\t\t\tclientAlok.p12\n\n6) `Import Alok Client Cert (clientAlok.p12) to browser` - so that when communicating to localhost this certificate will be sent for Authentication:\n\t\n\n\t\tType about:preferences in the address bar\n\t\tOpen Advanced -\u003e View Certificates -\u003e Your Certificates\n\t\tClick on Import\n\t\tSelect clientAlok.p12 file and click OK\n\t\tInput the password for your certificate and click OK\n\n7) `Hit the Secure URL`\n\t\n\t7.1) Using Firefox\n\t\n\t\thttps://localhost:8443/user\n\t\t\n\t\tIt will promt to select one of the installed client certificate in the Browser\n\t\t\n\t7.2) Hit the API URL using CURL\n\t\n\t\tcurl --cacert rootCA_Alok.crt --key clientAlok.key --cert clientAlok.crt https://localhost:8443/api/user\n\t\t\n\t\tWhere:\n\t\t\tcacert: Root CA Cert who signed server certificate (substitute of step 3)\n\t\t\tkey: Client Key (substitute of step 6)\n\t\t\tcert: Client Certificate (substitute of step 6)\n\t\t\t\n\t\tNote: for this step you may skip steps - 3, 5.3, and 6 (above)\n\n## Contents in Key Store and Truststore\n\n1) `Key Store`\n        \n\t- localhost.key\n\t- localhost.crt\n\n2) `Trust Store`\n        \n\t- rootCA_Alok.crt\n\n## TCP Dump and Analysis\n\nFind the dump file under dump/ folder. You may use Wiresark to read the dump file.\n\n1) `TCP Dump Command`\n````\nsudo tcpdump -i lo0 -n -s0 -w /Users/aloksingh/logs/x509App_04.cap port 8443\n````\n\nAssuming lo0 is loopback interface.\n\n2) `Dump Analysis`\n\n    ![alt text](https://github.com/alokkusingh/x509-authentication/blob/master/dump/dump.png?raw=true \"TCP Packets\")\n    \n    Note: The above screenshot is without decrypting the Application data. If you want to see the decrypted application data you need to extract `pre_master_secret_key` (symmetric key) from the dump using `ssldump` tool and pass the same key log file to Wireshark. So that Wireshark can decrypt the application dta using the symmetric key and show in here.\n    \n    - `[C \u003c-\u003e S]` `First 4` packets is for `TCP handshake`\n    - `[C \u003c-\u003e S]` `5` and `6` `Client Hello` and ACK from server\n    - `[C \u003c-- S]` `7` `Server Hello` along with \n                    `Server Certificate`,\n                    `Server Key Exchange`, \n                    `Certificate Request` (Mandatory for Mutual Authentication) \n    - `[C --\u003e S]` `8` ACK \n    - `[C --\u003e S]` `9` `Client Certificate` (Mandatory for Mutual Authentication) along with \n                    `Client Key Exchange` (for RSA, a 48-byte pre_master_secret (also known as session key) is generated by the client and encrypted using server public key, which can be decrypted only by private key server has), \n                    `Certificate Verify`, \n                    `Change Cipher Spec` (from now onwards to use symmetric key for encryption/decryption)\n    - `[C \u003c-- S]` `10` ACK\n    - `[C \u003c-- S]` `11` `Change Cipher Spec` (from now onwards to use symmetric key encryption/decryption - shared recently) \n    - `[C --\u003e S]` `12` ACK\n    - `[C \u003c-- S]` `13` `Encrypted Handshake Message` (Finished) - indicates TLS negotiations completed\n    - `[C --\u003e S]` `14` ACK\n    - `[C --\u003e S]` `15` GET request from Client\n    - `[C \u003c-- S]` `16` ACK \n    - `[C \u003c-- S]` `17` GET response from Server\n    - `[C --\u003e S]` `18` ACK\n    - `[C --\u003e S]` `19` `Encrypted Alert`\n    - `[C \u003c-- S]` `20` ACK\n    - `[C --\u003e S]` `21` FIN\n    - `[C \u003c-- S]` `22` ACK\n    \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falokkusingh%2Fx509-authentication","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falokkusingh%2Fx509-authentication","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falokkusingh%2Fx509-authentication/lists"}