This commit is contained in:
Patrick Roumanoff 2015-09-03 22:54:43 +10:00
parent bb4b4307ac
commit 17ea29f0d2
5 changed files with 95 additions and 76 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
bower_components
node_modules

View file

@ -5,68 +5,42 @@
<script src="base64url.js"></script> <script src="base64url.js"></script>
<script src="ssh-util.js"></script> <script src="ssh-util.js"></script>
<script src="keypair.js"></script> <script src="keypair.js"></script>
<style> <link rel="stylesheet" href="js-keygen.css">
label {
display: inline-block;
width: 80px;
}
select{
width: 200px;
}
input {
width: 180px;
}
</style>
</head> </head>
<body> <body>
<div><label for="name">Name:</label><input id="name" type="text" value="me@domain"></div> For an explanation on how this work, see the <a href="http://blog.roumanoff.com/">blog post</a>.<br>
<div><label for="alg">Algorithm:</label><select id="alg"><option value="RSASSA-PKCS1-v1_5" selected>RSASSA-PKCS1-v1_5</option></select> Usually you would want to save the private key to the machine initiating the ssh connection, and you want to copy the public key to the system receiving the connection.<br>
<label for="size">Size:</label><input id="size" type="text" value="2048"></div> No data is being sent to the server, everything happens within the context of this web page.
<div><label for="hash">Hash:</label><select id="hash"> <hr>
<option value="SHA-1">SHA-1</option> <div><label for="name">Name:</label><input id="name" type="text" value="webcrypto"></div>
<div><label for="alg">Algorithm:</label><select id="alg" disabled>
<option value="RSASSA-PKCS1-v1_5" selected>RSASSA-PKCS1-v1_5</option>
<option value="RSA-PSS">RSA-PSS</option>
<option value="ECDSA">ECDSA</option>
</select>
<label for="size">Size:</label><select id="size" disabled>
<option value="1024" selected>1024</option>
<option value="2048">2048</option>
<option value="4096">4096</option>
</select>
</div>
<div><label for="hash">Hash:</label><select id="hash" disabled>
<option value="SHA-1" selected>SHA-1</option>
<option value="SHA-256">SHA-256</option> <option value="SHA-256">SHA-256</option>
<option value="SHA-384">SHA-384</option> <option value="SHA-384">SHA-384</option>
<option value="SHA-512">SHA-512</option> <option value="SHA-512">SHA-512</option>
</select></div> </select></div>
<button id="generate">Generate</button> <label for="generate"></label><button id="generate">Generate</button>
<br> <br>
<hr>
<a id="private" style="display: none;" href="" download="id_rsa">id_rsa</a>
<a id="public" style="display: none;" href="" download="id_rsa.pub">id_rsa.pub</a>
Private Key <button id="copyPrivate">Copy</button> or <button id="savePrivate">Save</button><br>
<textarea id="privateKey" style="overflow: scroll; width: 650px; height: 150px; word-wrap:break-word;font-family: monospace;" spellcheck="false"></textarea>
<hr> <hr>
Public Key <button id="copyPublic">Copy</button> or <button id="savePublic">Save</button><br> <a id="private" style="display: none;" href="" download="id_rsa">id_rsa</a>
<textarea id="publicKey" style="width: 650px; height: 70px; word-wrap:break-word;font-family: monospace;" spellcheck="false"></textarea> <a id="public" style="display: none;" href="" download="id_rsa.pub">id_rsa.pub</a>
Private Key <button id="copyPrivate">Copy</button> or <button id="savePrivate">Save</button><br>
<script> <textarea id="privateKey" style="height: 150px;" spellcheck="false"></textarea>
function copy(id) {
return function() {
var ta = document.querySelector(id);
ta.focus();
ta.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copy key command was ' + msg);
} catch(err) {
console.log('Oops, unable to copy');
}
window.getSelection().removeAllRanges();
ta.blur();
}
}
document.querySelector('#savePrivate').addEventListener('click', function(event) {
document.querySelector('a#private').click();
});
document.querySelector('#copyPrivate').addEventListener('click', copy('#privateKey'));
document.querySelector('#savePublic').addEventListener('click', function(event) {
document.querySelector('a#public').click();
});
document.querySelector('#copyPublic').addEventListener('click', copy('#publicKey'));
</script>
<hr>
Public Key <button id="copyPublic">Copy</button> or <button id="savePublic">Save</button><br>
<textarea id="publicKey" spellcheck="false"></textarea>
</body> </body>
</html> </html>

18
js-keygen.css Normal file
View file

@ -0,0 +1,18 @@
label {
display: inline-block;
width: 80px;
}
select{
width: 200px;
}
input {
width: 180px;
}
textarea {
margin-top: 10px;
width: 650px;
height: 70px;
word-wrap: break-word;
font-family: monospace;
overflow: scroll;
}

45
keypair-ui.js Normal file
View file

@ -0,0 +1,45 @@
function copy(id) {
return function() {
var ta = document.querySelector(id);
ta.focus();
ta.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copy key command was ' + msg);
} catch(err) {
console.log('Oops, unable to copy');
}
window.getSelection().removeAllRanges();
ta.blur();
}
}
function buildHref(data) {
return "data:application/octet-stream;charset=utf-8;base64," + window.btoa(data);
}
document.addEventListener("DOMContentLoaded", function(event) {
document.querySelector('#savePrivate').addEventListener('click', function(event) {
document.querySelector('a#private').click();
});
document.querySelector('#copyPrivate').addEventListener('click', copy('#privateKey'));
document.querySelector('#savePublic').addEventListener('click', function(event) {
document.querySelector('a#public').click();
});
document.querySelector('#copyPublic').addEventListener('click', copy('#publicKey'));
document.querySelector('#generate').addEventListener('click', function(event) {
var name = document.querySelector('#name').value || "name";
var alg = document.querySelector('#alg').value || "RSASSA-PKCS1-v1_5";
var size = parseInt(document.querySelector('#size').value || "2048");
generateKeyPair(alg, size, name).then(function (keys) {
document.querySelector('#private').setAttribute("href", buildHref(keys[0]));
document.querySelector('#public').setAttribute("href", buildHref(keys[1]));
document.querySelector('#privateKey').textContent = keys[0];
document.querySelector('#publicKey').textContent = keys[1];
}).catch(function(err){
console.error(err);
});
});
});

View file

@ -48,23 +48,3 @@ function generateKeyPair(alg, size, name) {
return Promise.all([private, public]); return Promise.all([private, public]);
}); });
} }
function buildHref(data) {
return "data:application/octet-stream;charset=utf-8;base64," + window.btoa(data);
}
document.addEventListener("DOMContentLoaded", function(event) {
document.querySelector('#generate').addEventListener('click', function(event) {
var name = document.querySelector('#name').value || "name";
var alg = document.querySelector('#alg').value || "RSASSA-PKCS1-v1_5";
var size = parseInt(document.querySelector('#size').value || "2048");
generateKeyPair(alg, size, name).then(function (keys) {
document.querySelector('#private').setAttribute("href", buildHref(keys[0]));
document.querySelector('#public').setAttribute("href", buildHref(keys[1]));
document.querySelector('#privateKey').textContent = keys[0];
document.querySelector('#publicKey').textContent = keys[1];
}).catch(function(err){
console.error(err);
});
});
});