Created
August 19, 2015 02:36
-
-
Save hinzundcode/1450946e0823fc0d4db6 to your computer and use it in GitHub Desktop.
nodejs tls hpkp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var tls = require("tls"); | |
var fs = require("fs"); | |
var crypto = require("crypto"); | |
var options = { | |
host: "test.dev", | |
port: 8888, | |
ca: [fs.readFileSync("cert.pem"), fs.readFileSync("cert2.pem")], | |
}; | |
// cert fingerprint 99:5B:7B:AD:28:F4:7C:72:96:6C:24:9E:6A:63:A4:B0:AF:04:E5:43 | |
// openssl x509 -in cert.pem -outform DER | shasum | |
// hpkp base64 wh8TAnmj3IABejy1snFQdaqCjkFm73iArCmXKHGJGKc= | |
// hpkp: openssl x509 -in cert.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64 | |
function rsaPublicKeyDer(modulus_b64, exponent_b64) { | |
function prepadSigned(hexStr) { | |
msb = hexStr[0] | |
if ( | |
(msb>='8' && msb<='9') || | |
(msb>='a' && msb<='f') || | |
(msb>='A'&&msb<='F')) { | |
return '00'+hexStr; | |
} else { | |
return hexStr; | |
} | |
} | |
function toHex(number) { | |
var nstr = number.toString(16) | |
if (nstr.length%2==0) return nstr | |
return '0'+nstr | |
} | |
// encode ASN.1 DER length field | |
// if <=127, short form | |
// if >=128, long form | |
function encodeLengthHex(n) { | |
if (n<=127) return toHex(n) | |
else { | |
n_hex = toHex(n) | |
length_of_length_byte = 128 + n_hex.length/2 // 0x80+numbytes | |
return toHex(length_of_length_byte)+n_hex | |
} | |
} | |
var modulus = new Buffer(modulus_b64,'base64'); | |
var exponent = new Buffer(exponent_b64, 'base64'); | |
var modulus_hex = modulus.toString('hex') | |
var exponent_hex = exponent.toString('hex') | |
modulus_hex = prepadSigned(modulus_hex) | |
exponent_hex = prepadSigned(exponent_hex) | |
var modlen = modulus_hex.length/2 | |
var explen = exponent_hex.length/2 | |
var encoded_modlen = encodeLengthHex(modlen) | |
var encoded_explen = encodeLengthHex(explen) | |
var encoded_pubkey = '30' + | |
encodeLengthHex( | |
modlen + | |
explen + | |
encoded_modlen.length/2 + | |
encoded_explen.length/2 + 2 | |
) + | |
'02' + encoded_modlen + modulus_hex + | |
'02' + encoded_explen + exponent_hex; | |
var seq2 = | |
'30 0d ' + | |
'06 09 2a 86 48 86 f7 0d 01 01 01' + | |
'05 00 ' + | |
'03' + encodeLengthHex(encoded_pubkey.length/2 + 1) + | |
'00' + encoded_pubkey; | |
seq2 = seq2.replace(/ /g,''); | |
var der_hex = '30' + encodeLengthHex(seq2.length/2) + seq2; | |
der_hex = der_hex.replace(/ /g, ''); | |
return new Buffer(der_hex, 'hex'); | |
} | |
function rsaPublicKeyPem(modulus_b64, exponent_b64) { | |
var der = rsaPublicKeyDer(modulus_b64, exponent_b64); | |
var der_b64 = der.toString('base64'); | |
var pem = '-----BEGIN PUBLIC KEY-----\n' | |
+ der_b64.match(/.{1,64}/g).join('\n') | |
+ '\n-----END PUBLIC KEY-----\n'; | |
return pem | |
} | |
function generateHpbkPin(publicKeyDer) { | |
return crypto.createHash("sha256").update(publicKeyDer).digest("base64"); | |
} | |
function validateHpbkPin(peerCertificate, pin) { | |
var publicKey = rsaPublicKeyDer( | |
new Buffer(peerCertificate.modulus, "hex").toString("base64"), | |
new Buffer((peerCertificate.exponent.length % 2 ? "0" : "")+peerCertificate.exponent, "hex").toString("base64") | |
); | |
var hash = generateHpbkPin(publicKey); | |
return hash === pin; | |
} | |
var socket = tls.connect(options, function (err) { | |
console.log("connected"); | |
console.log(socket.getPeerCertificate()); | |
console.log(socket.getPeerCertificate().modulus); | |
console.log(socket.getPeerCertificate().exponent); | |
console.log(validateHpbkPin(socket.getPeerCertificate(), 'wh8TAnmj3IABejy1snFQdaqCjkFm73iArCmXKHGJGKc=')); | |
process.stdin.pipe(socket); | |
process.stdin.resume(); | |
}); | |
socket.setEncoding("utf8"); | |
socket.on("data", function (data) { | |
console.log(data); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment