How do I get public key hash for SSL pinning? - ios

How would I get the hash of a public certificate's info to be able to perform SSL Pinning in my application?
I am using TrustKit in my iOS application and it is asking for me to set the hash that I am expecting. Where can I get this from?

Since this is a programming web-site, i wanted to explain how to calculate the public key hash for Public Key Pinning. This is important because the algorithm is completely undocumented. (It's not even documented by the canonical RFC 7469 Public Key Pinning Extension for HTTP ! The RFC simply says "Use OpenSSL". That is a non-answer.)
tl;dr: Base64(SHA256(SubjectPublicKeyInfo))
A Certificate is not (just) a public key
The first important thing to realize is that a public key is just a number (e.g. 2,048 bit number for RSA). A certificate is a collection of a lot of additional information (subject names, hashes, digital signatures).
This means that:
a public key is a number
a certificate associates a web-site with that number (e.g. stackoverflow.com)
A public-key pin contains a hash of the public key. It is not the hash of the certificate. This lets you renew certificates while keeping your same public key.
The Certificate structure
We need to extract the public key from a certificate, so we need to know its structure. The structure of a certificate is documented (horribly) in RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
In programming terms, a Certificate is:
struct Certificate {
TBSCertificate tbsCertificate,
AlgorithmIdentifier signatureAlgorithm,
BITSTRING signatureValue
}
And it's the SubjectPublicKeyInfo inside the tbsCertificate that contains what we're after:
struct TBSCertificate {
EXPLICIT version,
CertificateSerialNumber serialNumber,
AlgorithmIdentifier signature,
Name issuer,
Validity validity,
Name subject,
SubjectPublicKeyInfo subjectPublicKeyInfo,
//...optional extra stuff...
}
We need to take the SHA256 of the raw subjectPublicKeyInfo.
digest = SHA256(certificate.tbsCertificate.subjectPublicKeyInfo);
That value, base64 encoded, becomes the value we put in our web-server response headers:
String pin = String.Format("max-age=%d; pin-sha256=\"%s\"",
31536000, //1 year
System.Convert.ToBase64(digest));
response.Headers.Add("Public-Key-Pins", pin);
For example:
Public-Key-Pins: max-age=31536000; pin-sha256="hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY=";
But what do i actually hash?
As an example of calculating the PKP SHA256 hash, i am going to use the current certificate of Facebook.com. You can browse to Facebook, view the certificate, and save it in a base64 encoded DER PEM:
Facebook.cer (PEM DER ASN.1 encoded)
-----BEGIN CERTIFICATE-----
MIIH5DCCBsygAwIBAgIQDACZt9eJyfZmJjF+vOp8HDANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
dXJhbmNlIFNlcnZlciBDQTAeFw0xNjEyMDkwMDAwMDBaFw0xODAxMjUxMjAwMDBa
MGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRMwEQYDVQQHEwpN
ZW5sbyBQYXJrMRcwFQYDVQQKEw5GYWNlYm9vaywgSW5jLjEXMBUGA1UEAwwOKi5m
YWNlYm9vay5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASg8YyvpzmIaFsT
Vg4VFbSnRe8bx+WFPCsE1GWKMTEi6qOS7WSdumWB47YSdtizC0Xx/wooFJxP3HOp
s0ktoHbTo4IFSjCCBUYwHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjsw
HQYDVR0OBBYEFMuYKIyhcufiMqmaPfINoYFWoRqLMIHHBgNVHREEgb8wgbyCDiou
ZmFjZWJvb2suY29tgg4qLmZhY2Vib29rLm5ldIIIKi5mYi5jb22CCyouZmJjZG4u
bmV0ggsqLmZic2J4LmNvbYIQKi5tLmZhY2Vib29rLmNvbYIPKi5tZXNzZW5nZXIu
Y29tgg4qLnh4LmZiY2RuLm5ldIIOKi54eS5mYmNkbi5uZXSCDioueHouZmJjZG4u
bmV0ggxmYWNlYm9vay5jb22CBmZiLmNvbYINbWVzc2VuZ2VyLmNvbTAOBgNVHQ8B
Af8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGA1UdHwRu
MGwwNKAyoDCGLmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWhhLXNlcnZl
ci1nNS5jcmwwNKAyoDCGLmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWhh
LXNlcnZlci1nNS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEF
BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwgYMG
CCsGAQUFBwEBBHcwdTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
Y29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
aUNlcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAA
MIICsAYKKwYBBAHWeQIEAgSCAqAEggKcApoAdgCkuQmQtBhYFIe7E6LMZ3AKPDWY
BPkb37jjd80OyA3cEAAAAVjl02IEAAAEAwBHMEUCIQDvWFsUeqWE/xwIYcXPvbb5
ExzfHBZTNwfnUf4RPO/lBgIgdOGmr0j7+u8/S+7tfFw71ZEjqpwJELl/sEFuQdPn
pwQBLwCsO5rtf6lnR1cVnm19V1Zy+dmBAJQem97/7KExO3V4LQAAAVjl02IoAAAE
AQEAYvnMV+BfP3Wrk4yFQE/Zx5WsjSabYOpLj1Tj5xFaoVoHdGqLCf/Hi+Vv0IRy
ePKFBCSW0+3eA589+WnCDMwcJlBYeZV8MlvHFZg3a66Uhx/OAvoetb0mCtUpnmIE
UwLX/eMNEvjg2qTH3/33ysCo2l25+/EcR8upF+2KIcmnk5WwaJzfq7cFPQc4Cvcz
mTHasJi/jmVaIaJ9HC50g3dx584TQX26lDLddF/Li4uEbJ7TSopnTzjQdWBtWbMF
h3bcfhFCKaqK2kIJV3bgup5HibEnZ2LPm6lekY072ZFCGM4QYc4ukqzou2JWCRmG
o0dMHJhnvQXpnIQGwATqCD4Q1AB2AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFcwO+U
mFXWidDdAAABWOXTYrkAAAQDAEcwRQIgGhXXbwUO5bD4Ts/Q0gqZwUS2vl/A4Hem
k7ovxl82v9oCIQCbtkflDXbcunY4MAQCbKlnesPGc/nftA84xDhJpxFHWQB3AO5L
vbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABWOXTZBEAAAQDAEgwRgIh
AKubngQoa5Iak8eCOrffH7Xx3AP1NMb5pFw35nt2VSeRAiEA47Kq1UQcDXIEsV+W
nuPd9LM5kpdeu0+TiHKtTLRQr0swDQYJKoZIhvcNAQELBQADggEBADrNSsoonbj1
YGjwy9t9wP9+kZBwrNMO2n5N5fQNhGawkEAX+lXlzgm3TqYlTNi6sCFbPBAErim3
aMVlWuOlctgnjtAdmdWZ4qEONrBLHPGgukDJ3Uen/EC/gwK6KdBCb4Ttp6MMPY1c
hb/ciTLi3QUUU4h4OJWqUjvccBCDs/LydNjKWZZTxLJmxRSmfpyCU3uU2XHHMNlo
8UTIlqZsOtdqhg7/Q/cvMDHDkcI/tqelmg0MD2H9KpcmAvVkwgjn+BVpv5HELl+0
EP0UhYknI1B6LBecJuj7jI26eXZdX35CYkpI/SZA9KK+OYKHh6vCxKqnRZ9ZQUOj
XnIWKQeV5Hg=
-----END CERTIFICATE-----
All the above is base64 encoded. Let's decode it into hex:
Facebook.cer (DER ASN.1 encoded)
30 82 07 e4 30 82 06 cc a0 03 02 01 02 02 10 0c 00 99 b7 d7 89 c9 f6 66 26 31 7e bc ea 7c 1c 30 0d 06 09 2a 86 48 86 f7
0d 01 01 0b 05 00 30 70 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 15 30 13 06 03 55 04 0a 13 0c 44 69 67 69 43 65 72 74
20 49 6e 63 31 19 30 17 06 03 55 04 0b 13 10 77 77 77 2e 64 69 67 69 63 65 72 74 2e 63 6f 6d 31 2f 30 2d 06 03 55 04 03
13 26 44 69 67 69 43 65 72 74 20 53 48 41 32 20 48 69 67 68 20 41 73 73 75 72 61 6e 63 65 20 53 65 72 76 65 72 20 43 41
30 1e 17 0d 31 36 31 32 30 39 30 30 30 30 30 30 5a 17 0d 31 38 30 31 32 35 31 32 30 30 30 30 5a 30 69 31 0b 30 09 06 03
55 04 06 13 02 55 53 31 13 30 11 06 03 55 04 08 13 0a 43 61 6c 69 66 6f 72 6e 69 61 31 13 30 11 06 03 55 04 07 13 0a 4d
65 6e 6c 6f 20 50 61 72 6b 31 17 30 15 06 03 55 04 0a 13 0e 46 61 63 65 62 6f 6f 6b 2c 20 49 6e 63 2e 31 17 30 15 06 03
55 04 03 0c 0e 2a 2e 66 61 63 65 62 6f 6f 6b 2e 63 6f 6d 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03
01 07 03 42 00 04 a0 f1 8c af a7 39 88 68 5b 13 56 0e 15 15 b4 a7 45 ef 1b c7 e5 85 3c 2b 04 d4 65 8a 31 31 22 ea a3 92
ed 64 9d ba 65 81 e3 b6 12 76 d8 b3 0b 45 f1 ff 0a 28 14 9c 4f dc 73 a9 b3 49 2d a0 76 d3 a3 82 05 4a 30 82 05 46 30 1f
06 03 55 1d 23 04 18 30 16 80 14 51 68 ff 90 af 02 07 75 3c cc d9 65 64 62 a2 12 b8 59 72 3b 30 1d 06 03 55 1d 0e 04 16
04 14 cb 98 28 8c a1 72 e7 e2 32 a9 9a 3d f2 0d a1 81 56 a1 1a 8b 30 81 c7 06 03 55 1d 11 04 81 bf 30 81 bc 82 0e 2a 2e
66 61 63 65 62 6f 6f 6b 2e 63 6f 6d 82 0e 2a 2e 66 61 63 65 62 6f 6f 6b 2e 6e 65 74 82 08 2a 2e 66 62 2e 63 6f 6d 82 0b
2a 2e 66 62 63 64 6e 2e 6e 65 74 82 0b 2a 2e 66 62 73 62 78 2e 63 6f 6d 82 10 2a 2e 6d 2e 66 61 63 65 62 6f 6f 6b 2e 63
6f 6d 82 0f 2a 2e 6d 65 73 73 65 6e 67 65 72 2e 63 6f 6d 82 0e 2a 2e 78 78 2e 66 62 63 64 6e 2e 6e 65 74 82 0e 2a 2e 78
79 2e 66 62 63 64 6e 2e 6e 65 74 82 0e 2a 2e 78 7a 2e 66 62 63 64 6e 2e 6e 65 74 82 0c 66 61 63 65 62 6f 6f 6b 2e 63 6f
6d 82 06 66 62 2e 63 6f 6d 82 0d 6d 65 73 73 65 6e 67 65 72 2e 63 6f 6d 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 07 80
30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 30 75 06 03 55 1d 1f 04 6e
30 6c 30 34 a0 32 a0 30 86 2e 68 74 74 70 3a 2f 2f 63 72 6c 33 2e 64 69 67 69 63 65 72 74 2e 63 6f 6d 2f 73 68 61 32 2d
68 61 2d 73 65 72 76 65 72 2d 67 35 2e 63 72 6c 30 34 a0 32 a0 30 86 2e 68 74 74 70 3a 2f 2f 63 72 6c 34 2e 64 69 67 69
63 65 72 74 2e 63 6f 6d 2f 73 68 61 32 2d 68 61 2d 73 65 72 76 65 72 2d 67 35 2e 63 72 6c 30 4c 06 03 55 1d 20 04 45 30
43 30 37 06 09 60 86 48 01 86 fd 6c 01 01 30 2a 30 28 06 08 2b 06 01 05 05 07 02 01 16 1c 68 74 74 70 73 3a 2f 2f 77 77
77 2e 64 69 67 69 63 65 72 74 2e 63 6f 6d 2f 43 50 53 30 08 06 06 67 81 0c 01 02 02 30 81 83 06 08 2b 06 01 05 05 07 01
01 04 77 30 75 30 24 06 08 2b 06 01 05 05 07 30 01 86 18 68 74 74 70 3a 2f 2f 6f 63 73 70 2e 64 69 67 69 63 65 72 74 2e
63 6f 6d 30 4d 06 08 2b 06 01 05 05 07 30 02 86 41 68 74 74 70 3a 2f 2f 63 61 63 65 72 74 73 2e 64 69 67 69 63 65 72 74
2e 63 6f 6d 2f 44 69 67 69 43 65 72 74 53 48 41 32 48 69 67 68 41 73 73 75 72 61 6e 63 65 53 65 72 76 65 72 43 41 2e 63
72 74 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 82 02 b0 06 0a 2b 06 01 04 01 d6 79 02 04 02 04 82 02 a0 04 82 02 9c
02 9a 00 76 00 a4 b9 09 90 b4 18 58 14 87 bb 13 a2 cc 67 70 0a 3c 35 98 04 f9 1b df b8 e3 77 cd 0e c8 0d dc 10 00 00 01
58 e5 d3 62 04 00 00 04 03 00 47 30 45 02 21 00 ef 58 5b 14 7a a5 84 ff 1c 08 61 c5 cf bd b6 f9 13 1c df 1c 16 53 37 07
e7 51 fe 11 3c ef e5 06 02 20 74 e1 a6 af 48 fb fa ef 3f 4b ee ed 7c 5c 3b d5 91 23 aa 9c 09 10 b9 7f b0 41 6e 41 d3 e7
a7 04 01 2f 00 ac 3b 9a ed 7f a9 67 47 57 15 9e 6d 7d 57 56 72 f9 d9 81 00 94 1e 9b de ff ec a1 31 3b 75 78 2d 00 00 01
58 e5 d3 62 28 00 00 04 01 01 00 62 f9 cc 57 e0 5f 3f 75 ab 93 8c 85 40 4f d9 c7 95 ac 8d 26 9b 60 ea 4b 8f 54 e3 e7 11
5a a1 5a 07 74 6a 8b 09 ff c7 8b e5 6f d0 84 72 78 f2 85 04 24 96 d3 ed de 03 9f 3d f9 69 c2 0c cc 1c 26 50 58 79 95 7c
32 5b c7 15 98 37 6b ae 94 87 1f ce 02 fa 1e b5 bd 26 0a d5 29 9e 62 04 53 02 d7 fd e3 0d 12 f8 e0 da a4 c7 df fd f7 ca
c0 a8 da 5d b9 fb f1 1c 47 cb a9 17 ed 8a 21 c9 a7 93 95 b0 68 9c df ab b7 05 3d 07 38 0a f7 33 99 31 da b0 98 bf 8e 65
5a 21 a2 7d 1c 2e 74 83 77 71 e7 ce 13 41 7d ba 94 32 dd 74 5f cb 8b 8b 84 6c 9e d3 4a 8a 67 4f 38 d0 75 60 6d 59 b3 05
87 76 dc 7e 11 42 29 aa 8a da 42 09 57 76 e0 ba 9e 47 89 b1 27 67 62 cf 9b a9 5e 91 8d 3b d9 91 42 18 ce 10 61 ce 2e 92
ac e8 bb 62 56 09 19 86 a3 47 4c 1c 98 67 bd 05 e9 9c 84 06 c0 04 ea 08 3e 10 d4 00 76 00 56 14 06 9a 2f d7 c2 ec d3 f5
e1 bd 44 b2 3e c7 46 76 b9 bc 99 11 5c c0 ef 94 98 55 d6 89 d0 dd 00 00 01 58 e5 d3 62 b9 00 00 04 03 00 47 30 45 02 20
1a 15 d7 6f 05 0e e5 b0 f8 4e cf d0 d2 0a 99 c1 44 b6 be 5f c0 e0 77 a6 93 ba 2f c6 5f 36 bf da 02 21 00 9b b6 47 e5 0d
76 dc ba 76 38 30 04 02 6c a9 67 7a c3 c6 73 f9 df b4 0f 38 c4 38 49 a7 11 47 59 00 77 00 ee 4b bd b7 75 ce 60 ba e1 42
69 1f ab e1 9e 66 a3 0f 7e 5f b0 72 d8 83 00 c4 7b 89 7a a8 fd cb 00 00 01 58 e5 d3 64 11 00 00 04 03 00 48 30 46 02 21
00 ab 9b 9e 04 28 6b 92 1a 93 c7 82 3a b7 df 1f b5 f1 dc 03 f5 34 c6 f9 a4 5c 37 e6 7b 76 55 27 91 02 21 00 e3 b2 aa d5
44 1c 0d 72 04 b1 5f 96 9e e3 dd f4 b3 39 92 97 5e bb 4f 93 88 72 ad 4c b4 50 af 4b 30 0d 06 09 2a 86 48 86 f7 0d 01 01
0b 05 00 03 82 01 01 00 3a cd 4a ca 28 9d b8 f5 60 68 f0 cb db 7d c0 ff 7e 91 90 70 ac d3 0e da 7e 4d e5 f4 0d 84 66 b0
90 40 17 fa 55 e5 ce 09 b7 4e a6 25 4c d8 ba b0 21 5b 3c 10 04 ae 29 b7 68 c5 65 5a e3 a5 72 d8 27 8e d0 1d 99 d5 99 e2
a1 0e 36 b0 4b 1c f1 a0 ba 40 c9 dd 47 a7 fc 40 bf 83 02 ba 29 d0 42 6f 84 ed a7 a3 0c 3d 8d 5c 85 bf dc 89 32 e2 dd 05
14 53 88 78 38 95 aa 52 3b dc 70 10 83 b3 f2 f2 74 d8 ca 59 96 53 c4 b2 66 c5 14 a6 7e 9c 82 53 7b 94 d9 71 c7 30 d9 68
f1 44 c8 96 a6 6c 3a d7 6a 86 0e ff 43 f7 2f 30 31 c3 91 c2 3f b6 a7 a5 9a 0d 0c 0f 61 fd 2a 97 26 02 f5 64 c2 08 e7 f8
15 69 bf 91 c4 2e 5f b4 10 fd 14 85 89 27 23 50 7a 2c 17 9c 26 e8 fb 8c 8d ba 79 76 5d 5f 7e 42 62 4a 48 fd 26 40 f4 a2
be 39 82 87 87 ab c2 c4 aa a7 45 9f 59 41 43 a3 5e 72 16 29 07 95 e4 78
The above binary is encoded in DER flavor of ASN.1. We can use the excellent javascript ASN.1 decoder to decode it for us:
30 82 07 e4 ;30=SEQUENCE (0x07e4 bytes)
|- tbsCertificate
| 30 82 06 cc ;30=SEQUENCE (0x66cc bytes)
| |- Version (0x03 bytes)
| | a0 03 02 01 02
| |- SerialNumber (0x10 bytes)
| | 02 10 0c 00 99 b7 d7 89 c9 f6 66 26 31 7e bc ea 7c 1c
| |- Signature (0x0d bytes)
| | 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00
| |- Issuer (0x70 bytes)
| | 30 70 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 15 30 13 06 03 55 04 0a 13 0c 44 69 67 69 43 65 72 74 20 49 6e 63 31 19 30 17 06 03 55 04 0b 13 10 77 77 77 2e 64 69 67 69 63 65 72 74 2e 63 6f 6d 31 2f 30 2d 06 03 55 04 03 13 26 44 69 67 69 43 65 72 74 20 53 48 41 32 20 48 69 67 68 20 41 73 73 75 72 61 6e 63 65 20 53 65 72 76 65 72 20 43 41
| |- Validity (0x1e bytes)
| | 30 1e 17 0d 31 36 31 32 30 39 30 30 30 30 30 30 5a 17 0d 31 38 30 31 32 35 31 32 30 30 30 30 5a
| |- Subject (0x69 bytes)
| | 30 69 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 13 30 11 06 03 55 04 08 13 0a 43 61 6c 69 66 6f 72 6e 69 61 31 13 30 11 06 03 55 04 07 13 0a 4d 65 6e 6c 6f 20 50 61 72 6b 31 17 30 15 06 03 55 04 0a 13 0e 46 61 63 65 62 6f 6f 6b 2c 20 49 6e 63 2e 31 17 30 15 06 03 55 04 03 0c 0e 2a 2e 66 61 63 65 62 6f 6f 6b 2e 63 6f 6d
| |- SubjectPublicKeyInfo (0x59 bytes)
| | 30 59
| | |- AlgorithmIdentifier (0x13 bytes)
| | | 30 13
| | | 06 07 2a 86 48 ce 3d 02 01 ;Algorithm Object Identifier - 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type)
| | | 06 08 2a 86 48 ce 3d 03 01 07 ;Algorithm Object Identiifer - 1.2.840.10045.3.1.7 prime256v1 (ANSI X9.62 named elliptic curve)
| | |- SubjectPublicKey (0x42 bytes)
| | 03 42
| | 00 04 a0 f1 8c af a7 39 88 68 5b 13 56 0e 15 15 b4 a7 45 ef
| | 1b c7 e5 85 3c 2b 04 d4 65 8a 31 31 22 ea a3 92 ed 64 9d ba
| | 65 81 e3 b6 12 76 d8 b3 0b 45 f1 ff 0a 28 14 9c 4f dc 73 a9
| | b3 49 2d a0 76 d3
| |- issuerUniqueID [0]
| a3 82 05 4a
| 30 82 05 46 30 1f 06 03 55 1d 23 04 18 30 16 80 14 51 68 ff 90 af 02 07 75 3c cc d9 65 64 62 a2 12 b8 59 72 3b 30 1d 06
| 4b 8f 54 e3 e7 11 5a a1 5a 07 74 6a 8b 09 ff c7 8b e5 6f d0 84 72 78 f2 85 04 24 96 d3 ed de 03 9f 3d f9 69 c2 0c cc 1c
| 26 50 58 79 95 7c 32 5b c7 15 98 37 6b ae 94 87 1f ce 02 fa 1e b5 bd 26 0a d5 29 9e 62 04 53 02 d7 fd e3 0d 12 f8 e0 da
| a4 c7 df fd f7 ca c0 a8 da 5d b9 fb f1 1c 47 cb a9 17 ed 8a 21 c9 a7 93 95 b0 68 9c df ab b7 05 3d 07 38 0a f7 33 99 31
| da b0 98 bf 8e 65 5a 21 a2 7d 1c 2e 74 83 77 71 e7 ce 13 41 7d ba 94 32 dd 74 5f cb 8b 8b 84 6c 9e d3 4a 8a 67 4f 38 d0
| 75 60 6d 59 b3 05 87 76 dc 7e 11 42 29 aa 8a da 42 09 57 76 e0 ba 9e 47 89 b1 27 67 62 cf 9b a9 5e 91 8d 3b d9 91 42 18
| ce 10 61 ce 2e 92 ac e8 bb 62 56 09 19 86 a3 47 4c 1c 98 67 bd 05 e9 9c 84 06 c0 04 ea 08 3e 10 d4 00 76 00 56 14 06 9a
| 2f d7 c2 ec d3 f5 e1 bd 44 b2 3e c7 46 76 b9 bc 99 11 5c c0 ef 94 98 55 d6 89 d0 dd 00 00 01 58 e5 d3 62 b9 00 00 04 03
| 00 47 30 45 02 20 1a 15 d7 6f 05 0e e5 b0 f8 4e cf d0 d2 0a 99 c1 44 b6 be 5f c0 e0 77 a6 93 ba 2f c6 5f 36 bf da 02 21
| 00 9b b6 47 e5 0d 76 dc ba 76 38 30 04 02 6c a9 67 7a c3 c6 73 f9 df b4 0f 38 c4 38 49 a7 11 47 59 00 77 00 ee 4b bd b7
| 75 ce 60 ba e1 42 69 1f ab e1 9e 66 a3 0f 7e 5f b0 72 d8 83 00 c4 7b 89 7a a8 fd cb 00 00 01 58 e5 d3 64 11 00 00 04 03
| 00 48 30 46 02 21 00 ab 9b 9e 04 28 6b 92 1a 93 c7 82 3a b7 df 1f b5 f1 dc 03 f5 34 c6 f9 a4 5c 37 e6 7b 76 55 27 91 02
| 21 00 e3 b2 aa d5 44 1c 0d 72 04 b1 5f 96 9e e3 dd f4 b3 39 92 97 5e bb 4f 93 88 72 ad 4c b4 50 af 4b
|- signatureAlgorithm
| 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00
|- signatureValue
03 82 01 01
00 3a cd 4a ca 28 9d b8 f5 60 68 f0 cb db 7d c0 ff 7e 91 90 70 ac d3 0e da 7e 4d e5 f4 0d 84 66 b0
90 40 17 fa 55 e5 ce 09 b7 4e a6 25 4c d8 ba b0 21 5b 3c 10 04 ae 29 b7 68 c5 65 5a e3 a5 72 d8 27
8e d0 1d 99 d5 99 e2 a1 0e 36 b0 4b 1c f1 a0 ba 40 c9 dd 47 a7 fc 40 bf 83 02 ba 29 d0 42 6f 84 ed
a7 a3 0c 3d 8d 5c 85 bf dc 89 32 e2 dd 05 14 53 88 78 38 95 aa 52 3b dc 70 10 83 b3 f2 f2 74 d8 ca
59 96 53 c4 b2 66 c5 14 a6 7e 9c 82 53 7b 94 d9 71 c7 30 d9 68 f1 44 c8 96 a6 6c 3a d7 6a 86 0e ff
43 f7 2f 30 31 c3 91 c2 3f b6 a7 a5 9a 0d 0c 0f 61 fd 2a 97 26 02 f5 64 c2 08 e7 f8 15 69 bf 91 c4
2e 5f b4 10 fd 14 85 89 27 23 50 7a 2c 17 9c 26 e8 fb 8c 8d ba 79 76 5d 5f 7e 42 62 4a 48 fd 26 40
f4 a2 be 39 82 87 87 ab c2 c4 aa a7 45 9f 59 41 43 a3 5e 72 16 29 07 95 e4 78
Which is a lot
But the only part we care about is the SubjectPublicKeyInfo:
SubjectPublicKeyInfo (0x59 bytes)
| 30 59
| |- AlgorithmIdentifier (0x13 bytes)
| | 30 13
| | 06 07 2a 86 48 ce 3d 02 01 ;Algorithm Object Identifier - 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type)
| | 06 08 2a 86 48 ce 3d 03 01 07 ;Algorithm Object Identiifer - 1.2.840.10045.3.1.7 prime256v1 (ANSI X9.62 named elliptic curve)
| |- SubjectPublicKey (0x42 bytes)
| 03 42
| 00 04 a0 f1 8c af a7 39 88 68 5b 13 56 0e 15 15 b4 a7 45 ef
| 1b c7 e5 85 3c 2b 04 d4 65 8a 31 31 22 ea a3 92 ed 64 9d ba
| 65 81 e3 b6 12 76 d8 b3 0b 45 f1 ff 0a 28 14 9c 4f dc 73 a9
| b3 49 2d a0 76 d3
If you take just those bytes:
30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d
03 01 07 03 42 00 04 a0 f1 8c af a7 39 88 68 5b 13 56 0e 15
15 b4 a7 45 ef 1b c7 e5 85 3c 2b 04 d4 65 8a 31 31 22 ea a3
92 ed 64 9d ba 65 81 e3 b6 12 76 d8 b3 0b 45 f1 ff 0a 28 14
9c 4f dc 73 a9 b3 49 2d a0 76 d3
And run them through SHA256, you get:
SHA256: 854206f3b721ef511941885904492ad952812e386eb2c530ee747cc32b98eeb6 (hex)
You then base64 encode that, and you get:
base64: hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY=
That is the hash that you add to your HTTP response headers:
Public-Key-Pins: max-age=31536000; pin-sha256="hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY=";
Cross-check
Our calculated values matches the PKP hash that SSL Labs returns:
You can also paste the original PEM (base64) encoded certificate into https://certpins.appspot.com/pin and confirm that it returns the same PKP hash:
Public-Key-Pins: max-age=31536000;
 pin-sha256="hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY=";
Why SubjectPublicKeyInfo?
A public key is a number (or in the case of RSA a pair of numbers):
exponent (e.g. 65,537)
modulus (e.g. one hundred and fifty four million googol googol googol)
Over the years there are a number of ways of storing these two numbers:
SHH:
[lenghPrefix]ssh-rsa[lengthPrefix][exponent][lengthPrefix][modulus]
Xml
<RSAKeyValue>
<Modulus>ANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9V</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
PKCS#1
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXY
UMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE
3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dV
ek9b9VAgMBAAE=
-----END RSA PUBLIC KEY-----
PKCS#1 chose to use the DER flavor of ASN.1 encoding of the following structure:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
Later when new public key encryption systems came along, they "borrowed" the RSAPublicKey structure, but prefixed it with an Algorithm ID:
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey RSAPublicKey }
Where AlgorithID for PKCS#1 RSAPublicKey is 1.2.840.113549.1.1.1, which comes from:
1 - ISO assigned OIDs
1.2 - ISO member body
1.2.840 - USA
1.2.840.113549 - RSADSI
1.2.840.113549.1 - PKCS
1.2.840.113549.1.1 - PKCS-1
This format would then appear in base64 encoded files as:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcZ/r0nvJyHUUstIB5BqCUJ1CC
Cd1nzle4bEpPQJ/S0Wn7mV2FDAeh+UcbVhZu9n+5zypYNjeZKapPqBLoT8eCK51y
Kpzeb8LuEm3P8PK4xN18XBrIF1GprN8IIgSdK9f5SwnemutcURrY+PlWnvj7N5s/
03RlJA3/NHVXpPW/VQIDAQAB
-----END PUBLIC KEY-----
This is the SubjectPublicKeyInfo that you get the sha256 hash of.
Inside every certificate is a SubjectPublicKeyInfo; even a Windows EFS certificate.
You can use OpenSSL to:
extract the SubjectPublicKeyInfo chunk and save it as a BEGIN PUBLIC KEY file
hash it
base64 it
People need to stop treating OpenSSL as a magical crypto box. Too often, people just type in esoteric openssl commands to do something, rather than understanding what they're doing. Even the very RFC on Public Key Pinning doesn't bother to explain what it is, and just tells you to go to the all-knowing openssl. OpenSSL is not the be-all and end-off of encryption management.

If it is a public website, you can use SSL Labs server test which computes and displays the pin.
The Public Key Pinning page over at the Mozilla Developer Network also has commands for obtaining the pin from a key file, a certificate signing request, a certificate or a website (this is the one in #mylogon's answer).

There is a really straight forward way of doing this. I spent some time scraping things together on this one to produce a very reusable solution. Unfortunately, I have only done this on OSX, but you should be able to follow along fairly easy if you're on another OS.
For this method you are going to need:
Install Homebrew
OpenSSL (brew install openssl in terminal after installing Homebrew)
Create new .sh file and set contents to be:
openssl s_client -servername $1 -connect $1:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
Save file to disk
From terminal window, call bash <new sh file directory> www.google.com
This should now return the hash that you require and leave you with a nice little reusable solution. You may have to press ctrl+c after the hash is returned.
It should leave you with something like the following:
Hope this helps someone out.
Thanks

Assuming you have openssl and the certificate file, you can use this command taken from here.
openssl x509 -in my-certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

Related

How to get to know TCP or UDP protocol from wireshark pcap hexadecimal view

A sample TCP hexadecimal Wireshark capture shown below,
0000 6c 6a 77 8d 48 cf 96 38 a7 7d 02 de 08 00 45 28
0010 00 34 56 92 40 00 28 06 fa e9 a2 7d 13 09 c0 a8
0020 8a f1 01 bb df 84 20 00 27 8e e3 6f a9 7f 80 10
0030 00 7c 25 f3 00 00 01 01 08 0a 54 48 f8 cc 61 38
0040 eb 22
How to get to know TCP or UDP protocol from Wireshark pcap hexadecimal view ?.
Save the hex data, as shown, into a text file and then run text2pcap file.txt file.pcap. You can then load the file.pcap file into Wireshark. Run text2pcap -h for more help or refer to the text2pcap man page for more details about that tool.
0000 6c 6a 77 8d 48 cf 96 38 a7 7d 02 de 08 00 45 28
0010 00 34 56 92 40 00 28 06 fa e9 a2 7d 13 09 c0 a8
8th Byte in the second line we have to check. In here it's 06. So protocol number 06 is TCP. Like wise we can get to know the protocol number from hexadecimal view.

Delphi SmardCard response from hexadecimal string to string

I'm working with APDU commands and SmartCard. APDU command that I am sending to SmartCard is:
8813040000004A0000015D79403B6900000000000000000000003032313133313638320000000000000000000000415344333231363534000000000000249F000203000000000084AA0100000000024490 (Data converted to an array of bytes and printed as a hexadecimal string).
Response code is 9000(OK) and response data is:
0000015D79403B6900000000000000000000003032313133313638320000000000000000000000000000000000000000000000000000249F000000004D0000004D59984310375BFA315BD7D067A49535281665DBF0E76287A9A1D8E223AED0E2908DAE61A03B91FD965271B7980807E826174F33D3E65614191734C7FCBE5CF16652301905CC9E9364A42CCE2C59533C60420097D1725EAEECF883B51E4F9E17FED1F7D63B93C1B4D70D6A12275EA40F09C1321223BB760581DBAF7CA720C1EBA7A4016D66B02BFB1CD1902C46458EE22528D05564992D77E0DF2E1FC63093D45BB8BC493076E694C24C1FC1A29982C82674D27DB641510E07ADE48A586FC3CB05E28734A7ED7D86CA3D9E66EBBAE7B78EEDC7E8A567DB39A37D0B92C110540C20290055E2F90FC674FB4E39A34A76A5310ABC1C9CF5E48D499473EC0EAADF305F667E27987370E744153D3533FB6D93CE9835363DF2398677A96FE4A5CC0DAEFB344391F7F2A17C42E6CBE9E36254945A38A0EBD4B1D0A2167A8DD1D8B593F6EEC5C92D866D1423EC3ED89893F123D1923A3AD3E1AEDA424232D0C9B3A60C9E179B02BDF2DAFD00B810F35E608322619EF9D9D90B2512E3216B0EC4D3D36CE66505A1457767DA5D5542BEF57B2BB15B12A9F19495C74A9633395ADE2FD4A1639E1A53334BCE88D51937A786F002EDEEB96BA524C60D2623390D76437EC46F99C13BFA91A44FB348F72DCF8C020EE0F73607A7AFB1B568D09C059BA2B4361B02D1C46B1D31369D58488118BA20BBB99C3593A0775F9FAA4BA9241C6F5F6F4C4C84
SmardCard is supposed to sign and return data with signature (Certificate). It should be a string that I need for later but when I try to convert it back to string all I'm getting is vC~ÄoÁ;ú¤O³H÷-Ïà÷6§¯±µhТ´6ÑÄk16XHº »¹5 w_ªK©$o_oLL kind of a string that I can't actually use. Am I doing something wrong or missing any steps in between? How am I supposed to get that string from that hex response? Do I need to reverse bytes maybe (tried)?
Thanks in advance!
You are converting the returned data into a WideString (default string type in modern Delphi versions) but the returned data is actually in AnsiString format.
And if you want to view the returned data in a similar fashion that most browsers show digital certificate key value just add an empty space after every two characters.
For this you can use code like this:
//AStr is of AnsiString type
for I := Length(AStr)div 2 downto 1 do
begin
Insert(' ',AStr,I*2+1);
end;
The returned result will then be:
00 00 01 5D 79 40 3B 69 00 00 00 00 00 00 00 00 00 00 00 30 32 31 31 33 31 36 38 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 24 9F 00 00 00 00 4D 00 00 00 4D 59 98 43 10 37 5B FA 31 5B D7 D0 67 A4 95 35 28 16 65 DB F0 E7 62 87 A9 A1 D8 E2 23 AE D0 E2 90 8D AE 61 A0 3B 91 FD 96 52 71 B7 98 08 07 E8 26 17 4F 33 D3 E6 56 14 19 17 34 C7 FC BE 5C F1 66 52 30 19 05 CC 9E 93 64 A4 2C CE 2C 59 53 3C 60 42 00 97 D1 72 5E AE EC F8 83 B5 1E 4F 9E 17 FE D1 F7 D6 3B 93 C1 B4 D7 0D 6A 12 27 5E A4 0F 09 C1 32 12 23 BB 76 05 81 DB AF 7C A7 20 C1 EB A7 A4 01 6D 66 B0 2B FB 1C D1 90 2C 46 45 8E E2 25 28 D0 55 64 99 2D 77 E0 DF 2E 1F C6 30 93 D4 5B B8 BC 49 30 76 E6 94 C2 4C 1F C1 A2 99 82 C8 26 74 D2 7D B6 41 51 0E 07 AD E4 8A 58 6F C3 CB 05 E2 87 34 A7 ED 7D 86 CA 3D 9E 66 EB BA E7 B7 8E ED C7 E8 A5 67 DB 39 A3 7D 0B 92 C1 10 54 0C 20 29 00 55 E2 F9 0F C6 74 FB 4E 39 A3 4A 76 A5 31 0A BC 1C 9C F5 E4 8D 49 94 73 EC 0E AA DF 30 5F 66 7E 27 98 73 70 E7 44 15 3D 35 33 FB 6D 93 CE 98 35 36 3D F2 39 86 77 A9 6F E4 A5 CC 0D AE FB 34 43 91 F7 F2 A1 7C 42 E6 CB E9 E3 62 54 94 5A 38 A0 EB D4 B1 D0 A2 16 7A 8D D1 D8 B5 93 F6 EE C5 C9 2D 86 6D 14 23 EC 3E D8 98 93 F1 23 D1 92 3A 3A D3 E1 AE DA 42 42 32 D0 C9 B3 A6 0C 9E 17 9B 02 BD F2 DA FD 00 B8 10 F3 5E 60 83 22 61 9E F9 D9 D9 0B 25 12 E3 21 6B 0E C4 D3 D3 6C E6 65 05 A1 45 77 67 DA 5D 55 42 BE F5 7B 2B B1 5B 12 A9 F1 94 95 C7 4A 96 33 39 5A DE 2F D4 A1 63 9E 1A 53 33 4B CE 88 D5 19 37 A7 86 F0 02 ED EE B9 6B A5 24 C6 0D 26 23 39 0D 76 43 7E C4 6F 99 C1 3B FA 91 A4 4F B3 48 F7 2D CF 8C 02 0E E0 F7 36 07 A7 AF B1 B5 68 D0 9C 05 9B A2 B4 36 1B 02 D1 C4 6B 1D 31 36 9D 58 48 81 18 BA 20 BB B9 9C 35 93 A0 77 5F 9F AA 4B A9 24 1C 6F 5F 6F 4C 4C 84
Is this the result you are looking for?

What are these weird ha:// URLs jenkins fills our logs with?

We noticed our Jenkins build logs were being filled with 10 times more content than we expected. This greatly increases the amount of logs that slaves have to send back to the master, which in turn makes all builds take longer, which in turn makes builds fail with spurious timeouts.
On investigation, we find the lines all have a huge URL prepended.
ha:////{320 bytes of base64 junk} Log message
ha:////{320 bytes of base64 junk} [blank line]
ha:////{320 bytes of base64 junk} Next log message
I tried decoding the base64, but it doesn't produce any structure which I'm familiar with.
I didn't want to post ours because someone who knows how to decode it might find private info in there, but I tried searching for some of the content we were seeing, and noticed that someone else had posted the same sort of thing to pastebin:
https://pastebin.com/LM7mht8W
Taking one of those URLs:
ha:////4HTWhKVov8LrT80csqfIVuXrtfeJTJod3fz9PpkDu0UAAAAAzh+LCAAAAAAAAP9b85aBtbiIQSOjNKU4P0+vIKc0PTOvWK8kMze1uCQxtyC1SC8ExvbLL0llgABGJgYmLwaB3MycnMzi4My85FTXgvzkDB8G3tScxILi1BRfsEwJg4BPVmJZon5OYl66vk9+Xrp1RRGDFNSy5Py84vycVD1nCI1qPENFAZCOr07/fwfoPj6QKXogU/TApnQ/mXCmX/k+EwOjFwNrWWJOaSrQXAGEIr/S3KTUorY1U2W5pzzohprGwMDU+O4jAJgnACXyAAAA
And decoding it (including the ////):
00000000 ff ff ff e0 74 d6 84 a5 68 bf c2 eb 4f cd 1c b2 |....t...h...O...|
00000010 a7 c8 56 e5 eb b5 f7 89 4c 9a 1d dd fc fd 3e 99 |..V.....L.....>.|
00000020 03 bb 45 00 00 00 00 ce 1f 8b 08 00 00 00 00 00 |..E.............|
00000030 00 ff 5b f3 96 81 b5 b8 88 41 23 a3 34 a5 38 3f |..[......A#.4.8?|
00000040 4f af 20 a7 34 3d 33 af 58 af 24 33 37 b5 b8 24 |O. .4=3.X.$37..$|
00000050 31 b7 20 b5 48 2f 04 c6 f6 cb 2f 49 65 80 00 46 |1. .H/..../Ie..F|
00000060 26 06 26 2f 06 81 dc cc 9c 9c cc e2 e0 cc bc e4 |&.&/............|
00000070 54 d7 82 fc e4 0c 1f 06 de d4 9c c4 82 e2 d4 14 |T...............|
00000080 5f b0 4c 09 83 80 4f 56 62 59 a2 7e 4e 62 5e ba |_.L...OVbY.~Nb^.|
00000090 be 4f 7e 5e ba 75 45 11 83 14 d4 b2 e4 fc bc e2 |.O~^.uE.........|
000000a0 fc 9c 54 3d 67 08 8d 6a 3c 43 45 01 90 8e af 4e |..T=g..j<CE....N|
000000b0 ff 7f 07 e8 3e 3e 90 29 7a 20 53 f4 c0 a6 74 3f |....>>.)z S...t?|
000000c0 99 70 a6 5f f9 3e 13 03 a3 17 03 6b 59 62 4e 69 |.p._.>.....kYbNi|
000000d0 2a d0 5c 01 84 22 bf d2 dc a4 d4 a2 b6 35 53 65 |*.\..".......5Se|
000000e0 b9 a7 3c e8 86 9a c6 c0 c0 d4 f8 ee 23 00 98 27 |..<.........#..'|
000000f0 00 25 f2 00 00 00 |.%....|
000000f6
Noticing that 1f 8b 08 looked like a gzip header, I tried cutting the file at that point and decompressed it. This gave:
00000000 ac ed 00 05 73 72 00 28 68 75 64 73 6f 6e 2e 70 |....sr.(hudson.p|
00000010 6c 75 67 69 6e 73 2e 74 69 6d 65 73 74 61 6d 70 |lugins.timestamp|
00000020 65 72 2e 54 69 6d 65 73 74 61 6d 70 4e 6f 74 65 |er.TimestampNote|
00000030 00 00 00 00 00 00 00 01 02 00 02 4a 00 10 6d 69 |...........J..mi|
00000040 6c 6c 69 73 53 69 6e 63 65 45 70 6f 63 68 4c 00 |llisSinceEpochL.|
00000050 0d 65 6c 61 70 73 65 64 4d 69 6c 6c 69 73 74 00 |.elapsedMillist.|
00000060 10 4c 6a 61 76 61 2f 6c 61 6e 67 2f 4c 6f 6e 67 |.Ljava/lang/Long|
00000070 3b 78 72 00 1a 68 75 64 73 6f 6e 2e 63 6f 6e 73 |;xr..hudson.cons|
00000080 6f 6c 65 2e 43 6f 6e 73 6f 6c 65 4e 6f 74 65 00 |ole.ConsoleNote.|
00000090 00 00 00 00 00 00 01 02 00 00 78 70 00 00 01 5f |..........xp..._|
000000a0 7b 67 ff dc 73 72 00 0e 6a 61 76 61 2e 6c 61 6e |{g..sr..java.lan|
000000b0 67 2e 4c 6f 6e 67 3b 8b e4 90 cc 8f 23 df 02 00 |g.Long;.....#...|
000000c0 01 4a 00 05 76 61 6c 75 65 78 72 00 10 6a 61 76 |.J..valuexr..jav|
000000d0 61 2e 6c 61 6e 67 2e 4e 75 6d 62 65 72 86 ac 95 |a.lang.Number...|
000000e0 1d 0b 94 e0 8b 02 00 00 78 70 00 00 00 00 02 81 |........xp......|
000000f0 ee f1 |..|
000000f2
So it kind of seems like the timestamper plugin is somehow implicated in this nonsense, but when I go and read their code, I don't see anything about this stuff.
Which bit of Jenkins is actually doing this, and is there a way to avoid it?
Good detective work, #Trejkaz. Disabling the timestamper plugin did NOT fix things for me (I left the plugin installed; perhaps I should have removed it altogether or restarted Jenkins one more time to be sure).
My best answer (the one I'm using in practice) gets rid of all the escape sequences in the console AND in the context of this question, removes all of the 'ha:////' URLs as well so I get pretty close to unadorned, complete ASCII text in my processed console log. It's worth mentioning that our site's automation culture is to allow Jenkins builds to expire except those marked for keeping, so my workflow is to produce a postprocessed console log artifact to "keep" and not to archive the original log. It's not to create a smaller log in the first place, which I saw as more time- and resource-consuming for no discernible benefit.
Presuming the raw Jenkins console log lives in console-log.txt, it's:
ansi2txt < console-log.txt | col -b | sed 's;ha:////[[:print:]]*AAAA[=]*;;g'
This eliminates escape sequences meant to provide terminal display sugar without requiring build and installation of tool packages not found in any repo (in Ubuntu ansi2txt comes from colorized-logs and col comes from bsdmainutils), removes the mysterious 'ha:////' URLs regardless of their source, and turns a raw console log that looks like:
Started by user ESC[8mha:////4AqgegZw7qQ8DI1+KvWPDM7IJMwAv+ifWfXHqdHJJeCwAAAAlx+
LCAAAAAAAAP9b85aBtbiIQTGjNKU4P08vOT+vOD8nVc83PyU1x6OyILUoJzMv2y+/JJUBAhiZGBgqihh
k0NSjKDWzXb3RdlLBUSYGJk8GtpzUvPSSDB8G5tKinBIGIZ+sxLJE/ZzEvHT94JKizLx0a6BxUmjGOUN
odHsLgAzWEgZu/dLi1CL9xJTczDwAj6GcLcAAAAA=ESC[0mAdmin
Checking out git ssh://git#github.com/SlipChip/PHX-Inst-App-SW.git into /var/tmp
/meta-talis/workspace/Firmware-Inst-App-SW#script to read Jenkinsfile
...
Commit message: "Add Jenkins console log as artifact console-log.txt."
> git rev-list --no-walk b70ac257fc5c87aa4a1fe55661b3523842f43412 # timeout=10
Running in Durability level: MAX_SURVIVABILITY
ESC[8mha:////4Ke8FKbo31T+wvpwDtO0m31cw6Dr9enqafGE6M9os2Y7AAAAoh+LCAAAAAAAAP9tjTEOwjAQBM8BClpKHuFItIiK1krDC0x8GCfWnbEdkooX8TX+gCESFVvtrLSa5wtWKcKBo5UdUu8otU4GP9jS5Mixv3geZcdn2TIl9igbHBs2eJyx4YwwR1SwULBGaj0nRzbDRnX6rmuvydanHMu2V1A5c4MHCFXMWcf8hSnC9jqYxPTz/BXAFEIGsfuclm8zQVqFvQAAAA==ESC[0m[Pipeline] Start of Pipeline
ESC[8mha:////4IgCbJC4forU2exyZEKrDUTKRV7HgFuwndWEBhDMO34wAAAApR+LCAAAAAAAAP9tjTEOwjAUQ3+KOrAycohUghExsUZZOEFIQkgb/d8mKe3EibgadyBQiQlLlmxL1nu+oE4RjhQdby12HpP2vA+jK4lPFLtroIm3dOGaMFGwXNpJkrGnpUrKFhaxClYC1hZ1oOTRZdiIVt1VExS65pxj2Q4CKm8GeAAThZxVzN8yR9jeRpMIf5y/AJj7DGxXvP/86jduZBmjwAAAAA==ESC[0m[Pipeline] node
...
into the considerably more palatable:
Started by user Admin
Checking out git ssh://git#github.com/SlipChip/PHX-Inst-App-SW.git into /var/tmp/meta-talis/workspace/Firmware-Inst-App-SW#script to read Jenkinsfile
...
Commit message: "Add Jenkins console log as artifact console-log.txt."
> git rev-list --no-walk b70ac257fc5c87aa4a1fe55661b3523842f43412 # timeout=10
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
which is the same as what I see in the Jenkins web interface when browsing the console log.
I hope this answer helps you in a practical sense (i.e. rather than making an O(n) walkthrough of all of your plugins searching for the 'ha:////' culprit).

Neo4j bolt driver ClientException

I have loaded about 20000 odd nodes from the consumer complaints csv file available in the neo4j load csv example. I am using Neo4j bolt driver in my java class to query .
Driver driver = GraphDatabase.driver( "bolt://localhost/trialschema", AuthTokens.basic( "neo4j", "neo" ) );
Session session = driver.session();
StatementResult result = session.run( "MATCH(n)-[r]-(m) return n,type(r),m limit 10" );
Map<String,Object> resultOfQuery = processResult(result);
session.close();
driver.close();
return returnMap ;
But when I am trying to loop through this StatementResult, inside processResult Method, I get the below exception
There was an unexpected error (type=Internal Server Error,
status=500).
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is
org.neo4j.driver.v1.exceptions.ClientException: Trying to read message
complete ending '00 00' while there are more data left in the message
content unread: buffer [41 49 4e 53 54 b3 4e c9 77 af 91 89 43 6f 6d
70 6c 61 69 6e 74 a1 82 69 64 ca 00 1d 13 40 00 00 00 46 b1 71 93 b3
4e 07 91 87 43 6f 6d 70 61 6e 79 a1 84 6e 61 6d 65 8f 42 41 4e 4b 20
4f 46 20 41 4d 45 52 49 43 41 87 41 47 41 49 4e 53 54 b3 4e c9 77 9c
91 89 43 6f 6d 70 6c 61 69 6e 74 a1 82 69 64 ca 00 1b d4 06 00 00 00
46 b1 71 93 b3 4e 07 91 87 43 6f 6d 70 61 6e 79 a1 84 6e 61 6d 65 8f
42 41 4e 4b 20 4f 46 20 41 4d 45 52 49 43 41 87 41 47 41 49 4e 53 54
b3 4e c9 77 a4 91 89 43 6f 6d 70 6c 61 69 6e 74 a1 82 69 64 ca 00 1d
3c 54 00 00 00 46 b1 71 93 b3 4e 07 91 87 43 6f 6d 70 61 6e 79 a1 84
6e 61 6d 65 8f 42 41 4e 4b 20 4f 46 20 41 4d 45 52 49 43 41 87 41 47
41 49 4e 53 54 b3 4e c9 77 95 91 89 43 6f 6d 70 6c 61 69 6e 74 a1 82
69 64 ca 00 0b 56 ca 00 00 00 46 b1 71 93 b3 4e 07 91 87 43 6f 6d 70
61 6e 79 a1 84 6e 61 6d 65 8f 42 41 4e 4b 20 4f 46 20 41 4d 45 52 49
43 41 --------------unread chunk size 11075
I don't get this issue if I am trying to fetch only a small result by limiting the result to 50 or 100 . Can someone help ?

SSL/TLS connection monitoring/analysis

I want to show the client that my client/server app is using a secure connection with mutual authentication.
My server app is implemented using C#, and the client is using C with OpenSSL. They can talk to each other and work fine. I'm trying do this demonstration with the two solutions below, but I'm not satisfied with the results.
Monitoring the connection using SSLDump:
The output is listed below, seems to be nothing wrong with it, but not sure about that. Please help me with this.
Monitoring the connection using Wireshark, and Unsniff,
A network analysis tool, that can give me some kind of high level analysis result, could be very helpful with my demonstration. But when I watch the connection with these two tools, they all show me that the protocol is TCP, and I want they show me that protocol of the connection is SSL/TLS.
Any ideas?
Output from SSLDump:
fan#ubuntu:~/Desktop$ sudo ssldump -i eth0 port 9527 and host fan
New TCP connection #1: 192.168.181.144(60992) <-> fan.local(9527)
1 1 0.0044 (0.0044) C>S Handshake
ClientHello
Version 3.1
cipher suites
Unknown value 0xc014
Unknown value 0xc00a
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Unknown value 0x88
Unknown value 0x87
Unknown value 0xc00f
Unknown value 0xc005
TLS_RSA_WITH_AES_256_CBC_SHA
Unknown value 0x84
Unknown value 0xc012
Unknown value 0xc008
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
Unknown value 0xc00d
Unknown value 0xc003
TLS_RSA_WITH_3DES_EDE_CBC_SHA
Unknown value 0xc013
Unknown value 0xc009
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
Unknown value 0x9a
Unknown value 0x99
Unknown value 0x45
Unknown value 0x44
Unknown value 0xc00e
Unknown value 0xc004
TLS_RSA_WITH_AES_128_CBC_SHA
Unknown value 0x96
Unknown value 0x41
Unknown value 0xc011
Unknown value 0xc007
Unknown value 0xc00c
Unknown value 0xc002
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5
TLS_DHE_RSA_WITH_DES_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
TLS_RSA_EXPORT_WITH_RC4_40_MD5
Unknown value 0xff
compression methods
unknown value
NULL
1 2 0.2572 (0.2528) S>C Handshake
ServerHello
Version 3.1
session_id[32]=
5e 08 00 00 82 35 0d a1 2a 91 c2 ac cb 62 1e f5
d0 88 3a d3 1a 64 58 a3 11 be 56 ef c4 fe 73 b7
cipherSuite TLS_RSA_WITH_RC4_128_MD5
compressionMethod NULL
Certificate
CertificateRequest
certificate_types rsa_sign
certificate_types dss_sign
certificate_authority
30 4f 31 15 30 13 06 0a 09 92 26 89 93 f2 2c 64
01 19 16 05 6c 6f 63 61 6c 31 19 30 17 06 0a 09
92 26 89 93 f2 2c 64 01 19 16 09 4f 62 6a 65 63
74 69 76 61 31 1b 30 19 06 03 55 04 03 13 12 4f
62 6a 65 63 74 69 76 61 2d 42 4a 50 44 43 2d 43
41
certificate_authority
30 6f 31 0b 30 09 06 03 55 04 06 13 02 53 45 31
14 30 12 06 03 55 04 0a 13 0b 41 64 64 54 72 75
73 74 20 41 42 31 26 30 24 06 03 55 04 0b 13 1d
41 64 64 54 72 75 73 74 20 45 78 74 65 72 6e 61
6c 20 54 54 50 20 4e 65 74 77 6f 72 6b 31 22 30
20 06 03 55 04 03 13 19 41 64 64 54 72 75 73 74
20 45 78 74 65 72 6e 61 6c 20 43 41 20 52 6f 6f
74
certificate_authority
30 81 c1 31 0b 30 09 06 03 55 04 06 13 02 55 53
31 17 30 15 06 03 55 04 0a 13 0e 56 65 72 69 53
69 67 6e 2c 20 49 6e 63 2e 31 3c 30 3a 06 03 55
04 0b 13 33 43 6c 61 73 73 20 31 20 50 75 62 6c
69 63 20 50 72 69 6d 61 72 79 20 43 65 72 74 69
66 69 63 61 74 69 6f 6e 20 41 75 74 68 6f 72 69
74 79 20 2d 20 47 32 31 3a 30 38 06 03 55 04 0b
13 31 28 63 29 20 31 39 39 38 20 56 65 72 69 53
69 67 6e 2c 20 49 6e 63 2e 20 2d 20 46 6f 72 20
61 75 74 68 6f 72 69 7a 65 64 20 75 73 65 20 6f
6e 6c 79 31 1f 30 1d 06 03 55 04 0b 13 16 56 65
72 69 53 69 67 6e 20 54 72 75 73 74 20 4e 65 74
77 6f 72 6b
certificate_authority
...
certificate_authority
30 52 31 0b 30 09 06 03 55 04 06 13 02 55 53 31
0b 30 09 06 03 55 04 08 13 02 43 41 31 12 30 10
06 03 55 04 07 13 09 50 61 6c 6f 20 41 6c 74 6f
31 10 30 0e 06 03 55 04 0a 13 07 42 6f 78 2e 6e
65 74 31 10 30 0e 06 03 55 04 03 13 07 62 6f 78
2e 6e 65 74
certificate_authority
30 16 31 14 30 12 06 03 55 04 03 13 0b 58 59 5a
20 43 6f 6d 70 61 6e 79
ServerHelloDone
1 3 0.3889 (0.1316) C>S Handshake
Certificate
1 4 0.3889 (0.0000) C>S Handshake
ClientKeyExchange
1 5 0.3889 (0.0000) C>S Handshake
CertificateVerify
Signature[256]=
02 fb a2 32 cd 1f 43 6e e7 1c b6 d8 8e a0 cc 49
6e 04 17 fa 8d 86 b0 a5 98 23 b0 19 ec f2 a5 8d
65 2d 31 81 73 96 43 89 19 81 ea 60 c8 12 4a 86
99 a5 b1 7b b5 29 ee 57 46 39 32 b4 f4 df 49 e0
97 35 c8 a2 e1 12 98 21 fa 75 87 9a 84 17 82 ba
72 a1 60 0a 44 3b 72 97 88 0c 44 0b 7c 14 f5 01
1b 47 90 fb c0 0e dc ae 91 c3 a4 38 c9 b7 c5 37
52 d6 4e a1 fb d5 87 35 df a3 cb 28 ab 73 f6 c3
b5 11 48 fc db 9b 84 a2 35 b7 c8 42 df b0 7a 20
b3 20 52 f0 6c 29 ae 96 4c 32 2e ba af ea 2e ad
2d ee 2e ed da 49 f7 55 38 29 7e 90 62 a7 03 4f
cd 76 14 36 b2 e0 a6 73 f2 7c c3 04 7f c1 a7 ca
db 5b 97 84 a7 df c3 e6 a5 15 0b f1 d6 bf e0 8b
7c 62 55 c9 2b 24 2d ac 8c 7b c8 72 70 9c ef 77
c4 5b d5 32 a8 30 6f e7 43 46 f9 47 05 c6 b9 4a
9d 98 6b f4 b6 bd 82 14 ec 65 99 42 f0 a0 9b 18
1 6 0.3889 (0.0000) C>S ChangeCipherSpec
1 7 0.3889 (0.0000) C>S Handshake
1 8 0.5480 (0.1591) S>C ChangeCipherSpec
1 9 0.5480 (0.0000) S>C Handshake
1 10 0.5502 (0.0022) C>S application_data
1 11 0.5513 (0.0011) C>S application_data
1 12 0.5517 (0.0004) C>S application_data
1 13 0.5521 (0.0004) C>S application_data
1 14 0.6444 (0.0923) S>C application_data
1 15 9.8598 (9.2153) C>S application_data
1 16 10.2293 (0.3694) C>S application_data
1 12.3329 (2.1035) C>S TCP FIN
1 12.3401 (0.0072) S>C TCP FIN
This looks like a normal SSL/TLS negotiation with a Client and Server certificate exchange. However at least the client and maybe the server look like they are running TLS 1.0. The use of TLS 1.2 and a more secure block cipher could be good depending on your security requirements.

Resources