v1.1.0: add ssh fingerprint
This commit is contained in:
		
							vanhempi
							
								
									88f688184a
								
							
						
					
					
						commit
						6b6fd5e01d
					
				
							
								
								
									
										21
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								README.md
									
									
									
									
									
								
							@ -11,6 +11,7 @@ Features
 | 
			
		||||
< 100 lines of code | <1kb gzipped | 1.8kb minified | 3.1kb with comments
 | 
			
		||||
 | 
			
		||||
* [x] SSH Public Keys
 | 
			
		||||
  * fingerprint
 | 
			
		||||
* [x] RSA Public Keys
 | 
			
		||||
* [x] EC Public Keys
 | 
			
		||||
  * P-256 (prime256v1, secp256r1)
 | 
			
		||||
@ -47,18 +48,32 @@ ssh-to-jwk ~/.ssh/id_rsa.pub
 | 
			
		||||
 | 
			
		||||
You can also use it from JavaScript:
 | 
			
		||||
 | 
			
		||||
**SSH to JWK**
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
var sshtojwk = require('ssh-to-jwk');
 | 
			
		||||
 | 
			
		||||
var pub = fs.readFileSync("./id_rsa.pub");
 | 
			
		||||
var ssh = sshtojwk.parse(pub);
 | 
			
		||||
var ssh = sshtojwk.parse({ pub: pub });
 | 
			
		||||
 | 
			
		||||
console.info(ssh.jwk);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Legal
 | 
			
		||||
-----
 | 
			
		||||
**SSH Fingerprint**
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
var sshtojwk = require('ssh-to-jwk');
 | 
			
		||||
var pub = fs.readFileSync("./id_rsa.pub");
 | 
			
		||||
 | 
			
		||||
sshtojwk.fingerprint({ pub: pub }).then(function (fingerprint) {
 | 
			
		||||
  console.info(fingerprint);
 | 
			
		||||
  // SHA256:yCB62vBVsOwqksgYwy/WDbaMF2PhPijAwcrlzmrxfko
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Legal
 | 
			
		||||
 | 
			
		||||
[ssh-to-jwk.js](https://git.coolaj86.com/coolaj86/ssh-to-jwk.js) |
 | 
			
		||||
MPL-2.0 |
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,11 @@ if (!pubfile) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var buf = fs.readFileSync(pubfile);
 | 
			
		||||
var ssh = sshtojwk.parse(buf.toString('ascii'));
 | 
			
		||||
var pub = buf.toString('ascii');
 | 
			
		||||
var ssh = sshtojwk.parse({ pub: pub });
 | 
			
		||||
 | 
			
		||||
console.info(JSON.stringify(ssh.jwk, null, 2));
 | 
			
		||||
// Finally! https://superuser.com/a/714195
 | 
			
		||||
sshtojwk.fingerprint({ pub: pub }).then(function (fingerprint) {
 | 
			
		||||
  console.warn('The key fingerprint is:\n' + fingerprint + ' ' + ssh.comment);
 | 
			
		||||
  console.info(JSON.stringify(ssh.jwk, null, 2));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -3,49 +3,37 @@
 | 
			
		||||
var SSH = module.exports;
 | 
			
		||||
var Enc = require('./encoding.js');
 | 
			
		||||
 | 
			
		||||
SSH.parse = function (ssh) {
 | 
			
		||||
SSH.parse = function (opts) {
 | 
			
		||||
  var pub = opts.pub || opts;
 | 
			
		||||
  var ssh = SSH.parseBlock(pub);
 | 
			
		||||
  ssh = SSH.parseElements(ssh);
 | 
			
		||||
  //delete ssh.bytes;
 | 
			
		||||
  return SSH.parsePublicKey(ssh);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*global Promise*/
 | 
			
		||||
SSH.fingerprint = function (opts) {
 | 
			
		||||
  var ssh;
 | 
			
		||||
  if (opts.bytes) {
 | 
			
		||||
    ssh = opts;
 | 
			
		||||
  } else {
 | 
			
		||||
    ssh = SSH.parseBlock(opts.pub);
 | 
			
		||||
  }
 | 
			
		||||
  // for browser compat
 | 
			
		||||
  return Promise.resolve().then(function () {
 | 
			
		||||
    return 'SHA256:' + require('crypto').createHash('sha256')
 | 
			
		||||
      .update(ssh.bytes).digest('base64').replace(/=+$/g, '');
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
SSH.parseBlock = function (ssh) {
 | 
			
		||||
  ssh = ssh.split(/\s+/g);
 | 
			
		||||
 | 
			
		||||
  var result = { type: ssh[0], jwk: null, comment: ssh[2] || '' };
 | 
			
		||||
  var buf = Enc.base64ToBuf(ssh[1]);
 | 
			
		||||
  var els = SSH.parseElements({ bytes: buf }).elements;
 | 
			
		||||
  var typ = Enc.bufToBin(els[0]);
 | 
			
		||||
  var len;
 | 
			
		||||
 | 
			
		||||
  // RSA keys are all the same
 | 
			
		||||
  if (SSH.types.rsa === typ) {
 | 
			
		||||
    result.jwk = {
 | 
			
		||||
      kty: 'RSA'
 | 
			
		||||
    , n: Enc.bufToUrlBase64(els[2])
 | 
			
		||||
    , e: Enc.bufToUrlBase64(els[1])
 | 
			
		||||
    };
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // EC keys are each different
 | 
			
		||||
  if (SSH.types.p256 === typ) {
 | 
			
		||||
    len = 32;
 | 
			
		||||
    result.jwk = { kty: 'EC', crv: 'P-256' };
 | 
			
		||||
  } else if (SSH.types.p384 === typ) {
 | 
			
		||||
    len = 48;
 | 
			
		||||
    result.jwk = { kty: 'EC', crv: 'P-384' };
 | 
			
		||||
  } else {
 | 
			
		||||
    throw new Error("Unsupported ssh public key type: "
 | 
			
		||||
      + Enc.bufToBin(els[0]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // els[1] is just a repeat of a subset of els[0]
 | 
			
		||||
  var x = els[2].slice(1, 1 + len);
 | 
			
		||||
  var y = els[2].slice(1 + len, 1 + len + len);
 | 
			
		||||
 | 
			
		||||
  // I don't think EC keys use 0x00 padding, but just in case
 | 
			
		||||
  while (0x00 === x[0]) { x = x.slice(1); }
 | 
			
		||||
  while (0x00 === y[0]) { y = y.slice(1); }
 | 
			
		||||
 | 
			
		||||
  result.jwk.x = Enc.bufToUrlBase64(x);
 | 
			
		||||
  result.jwk.y = Enc.bufToUrlBase64(y);
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
  return {
 | 
			
		||||
    type: ssh[0]
 | 
			
		||||
  , bytes: Enc.base64ToBuf(ssh[1])
 | 
			
		||||
  , comment: ssh[2]
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
SSH.parseElements = function (ssh) {
 | 
			
		||||
@ -74,15 +62,56 @@ SSH.parseElements = function (ssh) {
 | 
			
		||||
    index += len;
 | 
			
		||||
  }
 | 
			
		||||
  if (fulllen !== index) {
 | 
			
		||||
    throw new Error(els.map(function (b) {
 | 
			
		||||
    throw new Error("invalid ssh public key length \n" + els.map(function (b) {
 | 
			
		||||
      return Enc.bufToHex(b);
 | 
			
		||||
    }).join('\n') + "invalid ssh public key length");
 | 
			
		||||
    }).join('\n'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ssh.elements = els;
 | 
			
		||||
  return ssh;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
SSH.parsePublicKey = function (ssh) {
 | 
			
		||||
  var els = ssh.elements;
 | 
			
		||||
  var typ = Enc.bufToBin(els[0]);
 | 
			
		||||
  var len;
 | 
			
		||||
 | 
			
		||||
  // RSA keys are all the same
 | 
			
		||||
  if (SSH.types.rsa === typ) {
 | 
			
		||||
    ssh.jwk = {
 | 
			
		||||
      kty: 'RSA'
 | 
			
		||||
    , n: Enc.bufToUrlBase64(els[2])
 | 
			
		||||
    , e: Enc.bufToUrlBase64(els[1])
 | 
			
		||||
    };
 | 
			
		||||
    return ssh;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // EC keys are each different
 | 
			
		||||
  if (SSH.types.p256 === typ) {
 | 
			
		||||
    len = 32;
 | 
			
		||||
    ssh.jwk = { kty: 'EC', crv: 'P-256' };
 | 
			
		||||
  } else if (SSH.types.p384 === typ) {
 | 
			
		||||
    len = 48;
 | 
			
		||||
    ssh.jwk = { kty: 'EC', crv: 'P-384' };
 | 
			
		||||
  } else {
 | 
			
		||||
    throw new Error("Unsupported ssh public key type: "
 | 
			
		||||
      + Enc.bufToBin(els[0]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // els[1] is just a repeat of a subset of els[0]
 | 
			
		||||
  var x = els[2].slice(1, 1 + len);
 | 
			
		||||
  var y = els[2].slice(1 + len, 1 + len + len);
 | 
			
		||||
 | 
			
		||||
  // I don't think EC keys use 0x00 padding, but just in case
 | 
			
		||||
  while (0x00 === x[0]) { x = x.slice(1); }
 | 
			
		||||
  while (0x00 === y[0]) { y = y.slice(1); }
 | 
			
		||||
 | 
			
		||||
  ssh.jwk.x = Enc.bufToUrlBase64(x);
 | 
			
		||||
  ssh.jwk.y = Enc.bufToUrlBase64(y);
 | 
			
		||||
 | 
			
		||||
  return ssh;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
SSH.types = {
 | 
			
		||||
  // 19 '00000013'
 | 
			
		||||
  // e c d s a - s h a 2 - n i s t p 2 5 6
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "ssh-to-jwk",
 | 
			
		||||
  "version": "1.0.2",
 | 
			
		||||
  "version": "1.1.0",
 | 
			
		||||
  "description": "💯 SSH to JWK in a lightweight, zero-dependency library.",
 | 
			
		||||
  "homepage": "https://git.coolaj86.com/coolaj86/ssh-to-jwk.js",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
@ -29,6 +29,7 @@
 | 
			
		||||
    "RSA",
 | 
			
		||||
    "EC",
 | 
			
		||||
    "SSH",
 | 
			
		||||
    "fingerprint",
 | 
			
		||||
    "JWK",
 | 
			
		||||
    "ECDSA"
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
		Ladataan…
	
	
			
			x
			
			
		
	
		Viittaa uudesa ongelmassa
	
	Block a user