112 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html lang="en">
 | |
| <head>
 | |
|     <meta charset="utf-8">
 | |
|     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 | |
| 
 | |
|     <!-- Bootstrap CSS -->
 | |
|     <link rel="stylesheet" href="../public/css/styles.min.css">
 | |
|     <meta name="theme-color" content="#ffffff">
 | |
| 
 | |
|     <title>CSR generation in browser</title>
 | |
| </head>
 | |
| <body>
 | |
| <div class="container">
 | |
|     <h1>CSR generation in browser</h1>
 | |
|     <div class="row">
 | |
|         <div class="col-12">
 | |
|             <form id="csr-form">
 | |
|                 <div class="form-group">
 | |
|                     <label for="nameInput">Your name</label>
 | |
|                     <input type="text" class="form-control" id="nameInput" aria-describedby="nameHelp" required
 | |
|                            minlength="3">
 | |
|                     <small id="nameHelp" class="form-text text-muted">Please input your name as it should be added to
 | |
|                         your certificate</small>
 | |
|                 </div>
 | |
|                 <fieldset class="form-group">
 | |
|                     <legend>RSA Key Size</legend>
 | |
|                     <div class="form-check">
 | |
|                         <input class="form-check-input" type="radio" name="keySize" id="size3072" value="3072"
 | |
|                                checked>
 | |
|                         <label class="form-check-label" for="size3072">3072 Bit</label>
 | |
|                     </div>
 | |
|                     <div class="form-check">
 | |
|                         <input class="form-check-input" type="radio" name="keySize" id="size2048" value="2048">
 | |
|                         <label class="form-check-label" for="size2048">2048 Bit (not recommended)</label>
 | |
|                     </div>
 | |
|                     <div class="form-check">
 | |
|                         <input class="form-check-input" type="radio" name="keySize" id="size4096" value="4096">
 | |
|                         <label class="form-check-label" for="size4096">4096 Bit</label>
 | |
|                     </div>
 | |
|                     <small id="keySizeHelp" class="form-text text-muted">An RSA key pair will be generated in your
 | |
|                         browser. Longer key sizes provide better security but take longer to generate.</small>
 | |
|                 </fieldset>
 | |
|                 <button type="submit" id="gen-csr-button" class="btn btn-primary">Generate Signing Request</button>
 | |
|             </form>
 | |
|         </div>
 | |
|     </div>
 | |
|     <div id="status-block" class="d-none row">
 | |
|         <div class="col-12">
 | |
|             <div class="d-flex align-items-center">
 | |
|                 <strong id="status-text">Loading ...</strong>
 | |
|                 <div class="spinner-border ml-auto" id="status-spinner" role="status" aria-hidden="true"></div>
 | |
|             </div>
 | |
|         </div>
 | |
|     </div>
 | |
|     <pre id="key"></pre>
 | |
|     <pre id="csr"></pre>
 | |
| </div>
 | |
| <script src="../public/js/jquery.slim.min.js"></script>
 | |
| <script src="../public/js/forge.all.min.js"></script>
 | |
| <script src="../public/js/bootstrap.bundle.min.js"></script>
 | |
| <script>
 | |
|     const keyElement = document.getElementById('key');
 | |
|     document.getElementById('csr-form').onsubmit = function (event) {
 | |
|         const subject = event.target["nameInput"].value;
 | |
|         const keySize = parseInt(event.target["keySize"].value);
 | |
|         if (isNaN(keySize)) {
 | |
|             return false;
 | |
|         }
 | |
|         const spinner = document.getElementById('status-spinner');
 | |
|         const statusText = document.getElementById('status-text');
 | |
|         const statusBlock = document.getElementById('status-block');
 | |
|         statusBlock.classList.remove('d-none');
 | |
|         spinner.classList.remove('d-none');
 | |
| 
 | |
|         const state = forge.pki.rsa.createKeyPairGenerationState(keySize, 0x10001);
 | |
|         statusText.innerHTML = 'started key generation';
 | |
|         const startDate = new Date();
 | |
|         const step = function () {
 | |
|             let duration = (new Date()).getTime() - startDate.getTime();
 | |
|             let seconds = Math.floor(duration / 100) / 10;
 | |
|             if (!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
 | |
|                 setTimeout(step, 1);
 | |
|                 statusText.innerHTML = `key generation running for ${seconds} seconds`;
 | |
|             } else {
 | |
|                 statusText.innerHTML = `key generated in ${seconds} seconds`
 | |
|                 spinner.classList.add('d-none');
 | |
|                 const keys = state.keys;
 | |
|                 keyElement.innerHTML = forge.pki.privateKeyToPem(keys.privateKey);
 | |
|                 const csr = forge.pki.createCertificationRequest();
 | |
| 
 | |
|                 csr.publicKey = keys.publicKey;
 | |
|                 csr.setSubject([{
 | |
|                     name: 'commonName',
 | |
|                     value: subject,
 | |
|                     valueTagClass: forge.asn1.Type.UTF8,
 | |
|                 }]);
 | |
|                 csr.sign(keys.privateKey, forge.md.sha256.create());
 | |
| 
 | |
|                 const verified = csr.verify();
 | |
|                 if (verified) {
 | |
|                     document.getElementById("csr").innerHTML = forge.pki.certificationRequestToPem(csr);
 | |
|                 }
 | |
|             }
 | |
|         };
 | |
|         setTimeout(step);
 | |
|         return false;
 | |
|     };
 | |
| </script>
 | |
| </body>
 | |
| </html>
 | |
| 
 |