├── client.sh ├── client.js ├── express-server.js ├── ssl ├── server.csr ├── client.csr ├── client.key ├── server.key ├── server.crt ├── client.crt ├── ca.crt └── ca.key ├── README.md └── server.js /client.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | # Denied (no cert) 4 | curl -v -s -k https://localhost:5678 5 | 6 | # Approved (using CA signed cert) 7 | curl -v -s -k --key ssl/client.key --cert ssl/client.crt https://localhost:5678 -------------------------------------------------------------------------------- /client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Node Client to test the Server 3 | */ 4 | 5 | var https = require('https'); 6 | var fs = require('fs'); 7 | 8 | var options = { 9 | host: 'localhost', 10 | port: 5678, 11 | method: 'GET', 12 | path: '/', 13 | key: fs.readFileSync('ssl/client.key'), 14 | cert: fs.readFileSync('ssl/client.crt'), 15 | passphrase: 'password', // doesn't seem to work... 16 | headers: {} 17 | }; 18 | 19 | var req = https.request(options, function(res) { 20 | console.log(res); 21 | }); 22 | req.end(); 23 | -------------------------------------------------------------------------------- /express-server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Express version of server.js 3 | */ 4 | 5 | var express = require('express'); 6 | var fs = require('fs'); 7 | 8 | var options = { 9 | key: fs.readFileSync('ssl/server.key'), 10 | cert: fs.readFileSync('ssl/server.crt'), 11 | ca: fs.readFileSync('ssl/ca.crt'), 12 | requestCert: true, 13 | rejectUnauthorized: false 14 | }; 15 | 16 | var app = express.createServer(options); 17 | 18 | app.get('/', function(req, res) { 19 | req.client.authorized ? 20 | res.json({"status":"approved"}) : 21 | res.json({"status":"denied"}, 401); 22 | }); 23 | 24 | app.listen(5678); -------------------------------------------------------------------------------- /ssl/server.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBhDCB7gIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEh 3 | MB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEB 4 | AQUAA4GNADCBiQKBgQCe2ICAJ1uVWr3g223DVYJERrHXgm0JSCannkfB75NDP8rr 5 | 1uBiNNjl8/6ZDmsIBlsO2eV0XmlHUPcEOC1X7zaNe6nmBzD6OC3s+cUhFuiACZfw 6 | ByuwLv+CwE79btHyIbAtaOq5FYvjOKstyLcA98toueriq02zrJylQPza1q+ReQID 7 | AQABoAAwDQYJKoZIhvcNAQEFBQADgYEAax/DlTnefw8znKMC296nMywrgdsQy336 8 | 1fPKLIqXg//PILPlAFPiTaN5j5v9DkipDeFpHTFfkHjmV1vyPBGruJHNNHO+vlY1 9 | 2IEtm+Qdwnc0aGy69JlXr1BnLUD0Ohd5gSfA31RA/Nhz0DdprHQmjyWBODdvKJIr 10 | yHdakCLPmTU= 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /ssl/client.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBoDCCAQkCAQAwYDELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5p 3 | YTETMBEGA1UEBxMKUGl0dHNidXJnaDESMBAGA1UEChMJTm9kZSBBdXRoMREwDwYD 4 | VQQDEwhOb2RlQXV0aDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu+HfpGbg 5 | WOp/B1Sx6QlNO0XDjHqVEIOPCXvyx6y7//xjPNKLG2FTlROgUMTa0mm76milM9RY 6 | snpUcAMTnE/IAqRtvHTc2+pWCwDalww+w0HGdV4/aT9J0VPg2yY0AlMTplNg3hWz 7 | c7HQLLdeVZ5Pqd7MNiVe15EKKysXLWrieXkCAwEAAaAAMA0GCSqGSIb3DQEBBQUA 8 | A4GBAEM6qXtwsk83IK9EXVK5IhMxuo2JawqMBO9pHLv7jF2EEIOy+ZZ81wD9llA8 9 | h8zZrqKtVdV2NKH3CYxyWhtUYa4ZbeyfTJEmPq3ZTaBrczUSBYcZ34ck9KGjeNOq 10 | MaAXIRcm9xkOpQCzkEoeFObJGKYzx1oZ4Vv41ak3GetKzeA6 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Client side SSL certificate authentication in Node.js 2 | 3 | Includes 4 | 5 | - `server.js`: Example HTTPS Node.js server that validates the client cert 6 | - `express-server.js`: Example [express](http://expressjs.com/) version 7 | - `client.sh`: A bash script that demonstrates using `curl` as a client 8 | - `client.js`: A Node.js client example 9 | - `ssl`: Directory with a bunch of sample certs 10 | 11 | More coming soon. Wanted to recreate the work I did to demonstrate [client cert auth in nginx](blog.nategood.com/client-side-certificate-authentication-in-ngi). You can check it out for more info about the client side certs process. 12 | 13 | Notes 14 | 15 | - The passphrase on these keys are all "password" 16 | - All examples run on port 5678 for the sake of simplicity (port 443 works just as well assuming you have access) -------------------------------------------------------------------------------- /ssl/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,88E97AD0653C6EC1 4 | 5 | 2b1E790WNxJdU69gtExa4f81B+8eMmoccNI+rGdH0xIvNvrljQFlhbaGrwvec1hJ 6 | r4SIn0/cliLXCWkoljld50w/2iBE4iGgcGtibPYmTm3/bqe9Q+5a14CDhyQDM/Pe 7 | T8wAStIczZNzP4ns6vFYmNTWF1Fhn51HYwwR7sgfzQ0T8Sfe0pTgr1fqBNr+IZwY 8 | +wmDi2UUGHcGovEAcNeqvb7sNAV+cg/qV18r8JSZUK32VoG6OwfF5i3y8q2BSv5b 9 | qQf+xAV1IyL1/GUS6AB8FdpDiJCiuT/MZlGHy+wusbiNj1pk7cqaqnEVDe5Hghor 10 | TljJzxwqUuk0qRL3zwzbfGgBlbQhNGWeGMuEuCPc9A4l97UY0UPHLxYbNk1caZYl 11 | KY1LHkausBO1KQiM0xyXA7f9ru35Atb4Cn8e1gD3/+CMNq16AwCbptOCmlQuVcc1 12 | FsrOdrudSrF4xOosebP22ivt/sHa7jGahoKQZbY3WIUCwkYllPrTYCU9UYZ1FUHY 13 | MMCLDhSOrsPQVo7qoEHfy5WXIFUmc48hBijgPX6oWyKcb4dbBrfNqkAvGnw3EraR 14 | phlswCJMNNZrLA2YQqIYknuCaRCmV3bJ2RqK8Mt8NhLfir0R7bmM5/p//U6ACpuj 15 | w3V0JD3NgtYJeP7WtcOWWM20lBGPI3BbQJFPPytRH+1lrEJobZDo/gHczWsAJQ43 16 | h9HYit+VxohPByJf+30ChRSoLZ3yfpMUwl6E0KWDfAtMdBJ08uS1tQmPWOQCjZDg 17 | DCqPRX39YR7GRlp16ZkeDofnqkilA75OTuux8UsZeihjPCNjyXBNgg== 18 | -----END RSA PRIVATE KEY----- 19 | -------------------------------------------------------------------------------- /ssl/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,AC498BDB124D6037 4 | 5 | owgXebeHX0+zRelNbMhe2vanJ/DzuigmZzAoIWRYYV4GMvBrGRUBV0qsO2Xeh5QJ 6 | AsqnXjWgfGphwSSNgLJRq6u60GHjoSdFgSIvkhjPYBKz4qmt2QlOHUMwVsnpIYWL 7 | KJahKKF9DmRp2QQdUQzmka3mkwnxMiv6OiJICg/63VpchVKjUI23KXo8SFHWdgsd 8 | qwjC/SFbLXCmdFMggVqDt30UE9EQ5EuGtIuN96HT9BkngiNnioggqy8YLD4soUfL 9 | wTsCDI/QuvKF05e8M+pYOEacPdBvMbZ7JevayKw232swrV3XVRSw+YPE/d/0M3KS 10 | PcFY3Zhblc+xASnhWv+vu9DGF1+gP2iEouXmdxHpyipiYNwRpJQBJ0GmkG77ucWa 11 | iJWP+q8ycDEbzlODRTRNYD4LKm4I51UUDRXQhDGTMcpQ5iyI16bnxVG7Ij0jZZci 12 | Iev6XTzX6CBxaeVJHUdkzsWXtxL9drTtFstSj0GWtiEBBLtJGbe1oh+87iN/4Zvt 13 | b3/lwqpzBgJlVBxTh29Pco0AMk1zFn9md/cQ9l3Tu4AyiXbRFxA7liKVw622cTzt 14 | 7ckJWQepAhhq0pPQlbLnTJJFDzBfiAMOt5WLdk1fitutCZ/2ZhyYnHRN4nU3hswz 15 | hL9z8KW/0dRxBvtNGwSFnRGGnq8gx2+HoKC33PQSe0c/ftzHWXI0LXmGeSXQkhmR 16 | VVcD/DdnVJEJs8wPnBkxV8X3XIWSiJqvEIyNHhI3Wzoe4FqGkzv7e9jDrAqi2sb0 17 | K23K16JIHTfcT5ScpwhiviMdfYdWKR3VNlO+8IRnYF2n7sZCirs91A== 18 | -----END RSA PRIVATE KEY----- 19 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example server. Returns JSON indicating whether or not 3 | * the client provided an approved/signed certificate. 4 | */ 5 | 6 | var https = require('https'); 7 | var fs = require('fs'); 8 | 9 | var options = { 10 | // The Server's SSL Key 11 | key: fs.readFileSync('ssl/server.key'), 12 | // The Server's Cert 13 | cert: fs.readFileSync('ssl/server.crt'), 14 | // The CA (us in this case) 15 | ca: fs.readFileSync('ssl/ca.crt'), 16 | // Ask for the client's cert 17 | requestCert: true, 18 | // Don't automatically reject 19 | rejectUnauthorized: false 20 | }; 21 | 22 | https.createServer(options, function (req, res) { 23 | if (req.client.authorized) { 24 | res.writeHead(200, {"Content-Type":"application/json"}); 25 | res.end('{"status":"approved"}'); 26 | // console.log(req.client); 27 | console.log("Approved Client ", req.client.socket.remoteAddress); 28 | } else { 29 | res.writeHead(401, {"Content-Type":"application/json"}); 30 | res.end('{"status":"denied"}'); 31 | // console.log(req.client); 32 | console.log("Denied Client " , req.client.socket.remoteAddress); 33 | } 34 | }).listen(5678); -------------------------------------------------------------------------------- /ssl/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDejCCAWICAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV 3 | BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 4 | ZDAeFw0xMjAyMTgwNTQ1MDlaFw0xMzAyMTcwNTQ1MDlaMEUxCzAJBgNVBAYTAkFV 5 | MRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRz 6 | IFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ7YgIAnW5VaveDb 7 | bcNVgkRGsdeCbQlIJqeeR8Hvk0M/yuvW4GI02OXz/pkOawgGWw7Z5XReaUdQ9wQ4 8 | LVfvNo17qeYHMPo4Lez5xSEW6IAJl/AHK7Au/4LATv1u0fIhsC1o6rkVi+M4qy3I 9 | twD3y2i56uKrTbOsnKVA/NrWr5F5AgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAH+X 10 | RPR5v40PxeJEUZe5h0eAmPEGy+iswLno7wnrJ7g3XWP3coEZxZMC7kPr2EaWvSto 11 | +fPkxA6KqtYqL+WQG2mz9whd7qRsiAMv0RZ5J1FJ/bWkHqClEA5PcEVbx2Eiqulh 12 | ngOqAJA69z2JuT0x5jRY3DOrZ8kxOe/bjGwY6cR4pFK3U7M+lYtZQd39TWm+Lp9Q 13 | 7WzoRy7yW+Hkp1N1byHrAygVzsjzybuZZeSx8NflAscvqHGFGdoNdzeFMoVDuqIu 14 | V3ztOQ88pxTkFzGAEtp2WZDEph6keesvAUsckEcZvMV40J5YZVYDJ6ZDIdgPs7LK 15 | C2G2Y7uz8aL8W7uubm+ejyAZPqz020y0Zjl0obF5rG98wBjyCHpimCDbSjwK0dk0 16 | bvWtUKyTOCqT9sfnEvZGu8twSxc8cbvclTqLF4z2zjbupaV1FKqz0eqWs6kCfuQW 17 | pdcErQrjfXTn8NowixnGUYFGjYyke/6oHoQXCGQHsApE6P7nv60V03UmJY34ACZ3 18 | /uQfeTu7Z8Vy6nQzNM7Pr3vXXSj3VIvgFeGlcSxIYH0wsqMxMHhNW+8aFvCm3kV1 19 | f/+UOgUUhMo8ay4+JXxwLezPtu6uEwodIF8Ius82ypjxfB76BRnBJVcG5wqWyne4 20 | WmLObMY7pCVAAucrSIoWhVBFauwZcM1+o3qExmbP 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /ssl/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDlTCCAX0CAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV 3 | BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 4 | ZDAeFw0xMjAyMTgwNTQ2NTVaFw0xMzAyMTcwNTQ2NTVaMGAxCzAJBgNVBAYTAlVT 5 | MRUwEwYDVQQIEwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gxEjAQ 6 | BgNVBAoTCU5vZGUgQXV0aDERMA8GA1UEAxMITm9kZUF1dGgwgZ8wDQYJKoZIhvcN 7 | AQEBBQADgY0AMIGJAoGBALvh36Rm4FjqfwdUsekJTTtFw4x6lRCDjwl78sesu//8 8 | YzzSixthU5UToFDE2tJpu+popTPUWLJ6VHADE5xPyAKkbbx03NvqVgsA2pcMPsNB 9 | xnVeP2k/SdFT4NsmNAJTE6ZTYN4Vs3Ox0Cy3XlWeT6nezDYlXteRCisrFy1q4nl5 10 | AgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAHQ+03EMUiF+emwQNTpU0SyrAvCeT2Z0 11 | 0xlc6sK07zkkmOjCrb4AYY/CchEAB2kdyH/n/bJKGHoyxW8XzQ/8zoewD4DyJECG 12 | dmvKDjRhF40K7CnsgbIfCrKI7UOfguBFXyFGVNGoX0rBA1693CmMjwwjAX4iE7nG 13 | 8rc9ZRpiqjd5G4NS7A1DIGJXq5GE/niM8F3rR6kH8gL/qMgHNQSP3IDQteL4r/GG 14 | wHTPCg5Z9LhGe/+Z2V5kVoyuKd+CW16We99hGxkX84A4RqEsMU+itigza7bxsX+X 15 | lmKjJg+/WmJ5layCu717m/PXqb5rBsOfzcGtp8yymOdEgj/mtaLEECJpauzIeAbh 16 | JaFCxMSxVzOrzaX1ZAO3YWprTmGddp1/OeX9efFcTbmcD/B925wgfAK+3iqWmqvo 17 | 9VCDczzc7ifatNW/bW1fKNTD4jhiwXgb3jKBI2gclrbImO+Tt/xzbCNpW/IZmZxM 18 | bmyDxh4JR2wnyUtee6Xd4ehtts4NxtJRHvybghoyTcxyyPuWnntVGMG1PUpDpnly 19 | zlMtLOvLcPlZr52nJ+Tg1Jl3N/Kg+dbm2Ltz/rI03GPvhGZ3NElkHNngc4vNJkQq 20 | hqQXTBW8vSW3/wFq5Ccz4wRX/z1vmBLVGOiiOA26evu1mxROYVE7McJUXR/c4HEt 21 | j+LL8KLgFCbp 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /ssl/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFtTCCA52gAwIBAgIJAJJSfLUrN46dMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMTIwMjE4MDU0MTU2WhcNMTMwMjE3MDU0MTU2WjBF 5 | MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC 7 | CgKCAgEA1srRRmoBrsk3V/I8w5AMFh6hoAgvHWCOIDNeMOT4ATidutmULQP4Efz7 8 | yv2yFlUqhK/fKlGpc/IwT13kVrxJ2vHUL9yHX2Ue10YTo6WZ8WPCVQkDt2rS2dWI 9 | v7q2r8QNXFTQrxHbXlLDAMdiaPn0YDBx80PG5q4NeR0nOmoXth3jPJ4XCtecd/0U 10 | f5Yh8p0pjyMTRvj9IBKgWXRmJSxwcnAi7IoBd89aKlc3wInljnX8e6CeMRmBHZre 11 | nxh4deURh+uDod/sw2WlFETnVgcQk/G6i6mmT22s91Mb+4ORB/hRTbYrbEtErCNx 12 | cjJM379cF7GZ/dcBN4wrGs3igJMGWi27Bq+dLQU3xLyWht1KAffvydjvNOknWM8a 13 | FbQ3LV5BKkGSXnsvsBkkMg/tdA9yux9uxUAFiSFnzS8yZKg/9gEQkL3EiYFJLYZl 14 | e6MeeI9R+rEBl5x9CI6Av8Izf1EnAauUEXNl2L2oUoKKdVxS+Kwx7vihDmFPnplI 15 | RZEhOIragKXaz8l90qBvouFZEvxvVdPKqyrTCY7odNRQX1XeDAuLU8LOt4MQuAgV 16 | PcPI+cnyRcCkLzgdQBo7THVCGYPDiy9S46MukJ/F8kRNhfkOV5VGU2fUipAvlEfF 17 | knSTR9l1HrSjreCR9YyGa69u/drolTFZy/dcUkfIOyXESadNc70CAwEAAaOBpzCB 18 | pDAdBgNVHQ4EFgQUThqXxRmnbBlLUjA87DjP2EOQtXowdQYDVR0jBG4wbIAUThqX 19 | xRmnbBlLUjA87DjP2EOQtXqhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT 20 | b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQCS 21 | Uny1KzeOnTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQCMACRrGElQ 22 | 5x2Bsz7JNkqn8yRzal43Z/T3Qhcw7fDpvpcs7K1yysIbPOGfmWEtaPk197JORODf 23 | /3fzuC6XQfkHj5Y4mr8ycz2SsG9M6lHw8dP6LvrkQAyo7Z4d+QfA1Ta6RV/PZnIq 24 | pfivKDn3eR+d+cNB5PhkeyEz1Kd3EkJg7vEHfXN01j3mNqmKmJK1CbAmcACZvWeP 25 | /2zp+Dbe+OG/TErJLMapsrSqkiXMRKve5L5tOYxDDbupUB7/SMkbfic0OZ6iiKQn 26 | b9vFnjYNCOZvMWPG6pox2W4dWSK633DtIZrus14lOpuwkExW43oOh+PXXQa8ukT1 27 | 5ckXzV7kSZr92bQlmmvVGUJgi0eiJ2wNvlhBWtcFADIXPpuN0UYj2JskJs1lv9mQ 28 | UPf1RB++W1k7DY5qWeyHDE9JyEktTsrMqy6gs1audXQ55PlvU2yZo4xkQXrRhaDZ 29 | y95H1/GByqVEzOMYZ39563EFfPrruQrIhJQYozn6K63VO22Ylf5CL0y8t2oA6OF9 30 | qFkK2K+jWPWkvtXq7B6imFaYy/uB8BpCKzaHjypWiCuGvZILnnl0M0elKhJDZ5Qt 31 | Ff0DShq5obrH95RpTrNSWusKnWQUvUuyVQ4g84Z4c9aX3z8TK+JGuEDxLE01CRHJ 32 | Elx9kr5GfichfL0GIZBzHQjmvv6188TYsw== 33 | -----END CERTIFICATE----- 34 | -------------------------------------------------------------------------------- /ssl/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,949D9051DAACE3E0 4 | 5 | E4q+m9D9/8C2yd5ThCyMQWLALhAlvXhbFktL35F2Ec7qTBBcpenCoKs+EgOK/VgU 6 | 6v28dhsxRfuy9SzJ4N7X1ONgFlf3YeK/zaBdDsD9QEh735uxRdfHQL595CbLFva8 7 | ezUi5QcW0RY1qZFQtTAw1vQpquvBNzLm6wEyktCNIXATlmzcu5SQD1kJmP+Zk7ta 8 | pha2U3OkiG5SQBwBU3nRSyfCTjNjSwDj8w4kyiSi2xvBIxkobqce2DNLQ29OnNDP 9 | y4h6fljizLbhF1TXa0xRr0ai9dGQ2cFsJKsTzW7cpRsv65VwTCbvYjjPcGLTtmv4 10 | Qw+nHH9p69Fj+4iadEvGLyNU52FM+iYndLieB0gTIGdzodKu9uyOgjfmdzjq/GmQ 11 | NwSyeEDCkHG0ElwwymM+okFRlrMnRY+dm0hxEpfpozu6aAdBAqMQh2C988dommto 12 | IyhtfnFGt7i5P2kF442XvcCsq0cpn00X9twCEZiUeE64ORaq82NasS65EDAyNwIx 13 | jaQ+UbiDVr8K9zUNI0pK6xgi1BzCo7xn2zi1cJYFgmeS8co8Rk3bOqtyK/nUG9Em 14 | SuOOrsgTPW6g+IR2NPaXcotY02/fZxQ28ByO2raXea2nqWTnGJ51nKMI1qp9aaky 15 | A6YrvTgKEYj9F7ZQ6z4cQuXy2up29yGeFzpV5b+2An1kdCyYEFQrQLRrRSHvwkkj 16 | s9m5PALbRtle31OAMakqUPuYes4eLjYi1bYO1+kdqaeU7PDgiaOb0/4umTom/fu3 17 | mCgxAArRgWV6SVX4R0FItXNAGDn3noLC8rgKk+mbdff7R6HXgoqUiUUFM4ehYsW3 18 | 1VryiMsuCF0Nhr1G8tpBCaEEp06l3eywqaZP5MPXIUkR4GFefV3V6f1poi6JXjm0 19 | Cam7cqECs6qHqmF/qiRyEWRYJzYFWL/iYwwaS6+u2IaEonxfNIEqKJ3RfYt7kK1R 20 | GyQQgOlgqkvs79UITFOxXTQgtRPyIuca41FsdMAez03J77yur81hSSamNgRh30EC 21 | bKLectk96lE/tLlFuOLRQWQeGs/mq3X8CS9JZng4UnZuSdx6jgN0UXOlmOrQ7G+a 22 | 6W2YUbyg99iiMczCKVHxURG4ZTH8/q3HtzRCPVwSJ/XITHA8u82LQXx0jVXY16RT 23 | 3crMTcllH0leJUqgE1aGmSsXuLGAPh2+KQoPTU4bYOz82sugbvQe8La8tKeK6v6b 24 | uyIFe8PLu62f7FYWCyTrmMrDikoliEY82TTK9xKm3JQJ0wmYbLycQZjeUVIptMhW 25 | T2/3EpfKDcBofIKVyGIlwCoFiNiuqStlTnRVI3PKAfvsRnk+EmFYz+gbROfNGhIP 26 | FBS9nPnixvCoxFXaQInF9b2DGwNKoQ2Qc/rkzqOEAKHx42WTwIBL0wedadoiUtlG 27 | h4fEiqGKp8gTkicDRwwSjAUxCKZn/UhxKB2mCYX5uquaglexPwEVWQzLV6yhQnWh 28 | hxPiGXRBYkkyZwGtYk7S7mKSAkCGgUEJDM0Yg66y2G1fOnc4qitCHBxgGLbQvYqL 29 | 1Xw++NUmvJx+7TPR3Lx5P4xRo0ZqtLiU84w540mvO18fAkUpVLV5/tMxyEtDE+pS 30 | Szp4luS/Mvd6jvKm068RtHe4SkaWn6WhY1Cch/EnwW7XKH0XEYyAsbkUDkoivGZc 31 | eMuKetZmz2JiBmOme2D6H6v/RUG+xJUnqVcbMYhdBDZ0jKt8abgWnUAgCgeo35yr 32 | mPwFkF4JT1xvdneDfsT7p48X8AIUiQZuxTPjPu3RT3X6uttyNnzVR3b9WQe8SO30 33 | 1ktY19Vru4VclSUx36yjXdP4TCS02v0Zx3fOysc/xKv5AFKvOCB5BbKu13gSJLgM 34 | 9T3fzKN7oMvT7uToTlhAL5ohQfbe4lulnhejO83Pq78rFkK72ihqUc4QZDgn1JJm 35 | 4xeeGsDy3XJhaNgG6G1J8PV9fYuD1zA6rFjhjWz0sFlSnPC+UZJfvVJ+L7xN8LIo 36 | +HiWFgui0CBUFQ59ud887y8fjiOfW2wAJbzGEL2UIdrlOrmsmeOpHEWYtVQ9It+k 37 | 7joOWPvYLyiPPc8UUfiZt03AYS8Xe7Ro4gkNTIW1kRtRrKd5zDu6M+IcVYResghq 38 | ZV28XOUulFBKegy6/Dvwh9UiNCghWFq4nINisjYCpKZjVK1MS7JbA0X+4ztm00DJ 39 | JMC1astSN2Q8v8QT4KB7sSQSHS1MIahQDGYzd6+c1ffg1dgf/e+EWAGHWfIOnjjz 40 | b6y0QEAyRGFeA5Qdv8jH/uAQva3N9u7/Xb0bpRO9/coupQoMxO5qRV/G25UO/nmD 41 | SGXkuxyS0e6ouZAhnaNtJTg2oI2oVmZtwf/dTZcKukgc0rWVWtBN/X7syGBfTKvn 42 | QHCKGOFdNQ3b+KAq98tXQClU7zpPeoaIhsVD+OE9fdeM83RHK5WLP4NwklY7+5BR 43 | S7IL37qqi2IM+f+gFpJZ+1QnXpeW7OuuXvqChU9W+q33I1tnLcm+cAJCBAwcdJhg 44 | TmPYmd06/LX579X9xoIZBcWLlER4/LL7590OsJxS26djADczPznLKGR0u+posrqV 45 | 1A9YAPwSsvpz8EQ+JpOcxANxBvrdv9u5JwHsZ6pwPY7Gu8iy2W3dJpsYggSk9Ula 46 | OEKh1WlV2lkwY483sfsNt+NAcoeOZefR08AmYjTj22QAy9LilFx/LvL94P8RkzyO 47 | AYSEbv4KaxXXwqlQr9pxu9b1vQYRwdLBHBTGTcLizzNMvRT+s8WTZ/XGbwShDjv6 48 | XXeNaW3aN5pXhOweczi7QBSiFcZ+3CJ3OnRIt4Y+SEnw1ZyJ4tSqTGhqfrMcf0or 49 | h9CKOrbOQZTDCBGh7hGiMFbZk2OrUiFYktVUZuHCJTj2usqTVBV4KskAc5bIBPQN 50 | NbmyccLucszQAv5d7Vp33I1VWGom+Wq1zIDSyGBNKuYqNaNCIL2pgEM0KRFFu9lM 51 | SWf+qQT53vpHOcAeGGLIObi6WvKmOpts+xyy1sKHNDWEJi3P4aYPBcNyvb83vcNe 52 | bOFHxgaeAbdwu4xsHLan45MTqx+kEjFES0uQQ7utg1D+vEEE++RYiJDRD1nPhMHM 53 | 1p5KcMPccL+yM0RsfILwEZVczoGbUlelkRUElHI3oNY4WPet8AvPTkFaLV0Q0KOx 54 | -----END RSA PRIVATE KEY----- 55 | --------------------------------------------------------------------------------