A First Look at MintChip's Hosted API's Crypto
April 07, 2012 at 08:05 PM | OpenSSL, MintChip | View CommentsThe Royal Canadian Mint announced a challenge last week, calling for developers to build software which uses MintChip. MintChip is a proposed digital currency which is decentralized, anonymous, and offline. The (currently scarce) details of the device and developer challenge can be found at mintchipchallenge.com.
A couple of friends and I have signed up to build something, and we just got the private keys and certificates necessary to interact with the "hosted MintChip" API.
Overview
Before I go into more detail, let me first explain: payments are processed by the "trusted"[0] MintChip hardware. This hardware can either be attached directly to the device facilitating a payment (for example, a smart phone), or hosted by a trusted 3rd party, allowing the MintChip to be used from any internet-connected device.
This is called the "hosted API", and this post deals with the cryptography used for authentication and privacy by the current implementation of the hosted API.
Once my physical devices arrive, I will write a post about them, provided they are sufficiently interesting.
[0]: at least, trusted in theory; if the hardware is compromised it would be possible to forge transactions (ex, double-spend, create new money, etc).
The Hosted API
Important notes:
- Everything here is educated guesswork, based only on the sparse MintChip documentation and the PKCS12 file which is used to access the hosted API.
- I am an x509 enthusiast but not an expert. If you are, I would very much appreciate it if you pointed out any inaccuracies or omissions.
- This is a developer preview of a proof-of-concept. There is no guarantee that the security of the final system will look anything at all like the system I'm describing here.
The first thing you'll notice when trying to access the hosted HTTPS API is that it signed with an "invalid" certificate (although this is for a sensible reason; keep reading):
$ curl https://remote.mintchipchallenge.com curl: (60) SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed More details here: http://curl.haxx.se/docs/sslcerts.html
And connecting anyway yields a 403 Forbidden (also, that they are running ASP.NET):
$ curl -Ik https://remote.mintchipchallenge.com HTTP/1.1 403 Forbidden Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET
HTTPS Server Certificate
Grabbing and dumping the certificate they are using:
$ openssl s_client -connect remote.mintchipchallenge.com:443 -showcerts \
> | openssl x509 -noout -text
...
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
Validity
Not Before: Mar 6 08:25:42 2012 GMT
Not After : Mar 7 08:25:42 2013 GMT
Subject: CN=remote.mintchipchallenge.com, OU=Remote MintChip Server, O=Royal Canadian Mint, C=CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:8e:1c:52:2f:c7:62:7d:05:0b:4a:80:4f:cb:91:
...
5a:90:60:58:f9:43:c8:bc:f1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: sha1WithRSAEncryption
58:34:a3:bd:f3:8d:17:b2:eb:4e:ed:f6:58:b0:13:3b:8c:79:
...
91:0d:59:81
...
Note that the certificate is issued by "Remote MintChip Authority". I suspect that MintChip chose to use their own CA both for simplicity (they don't need to deal with a 3rd party) and security. Apart from that, this certificate looks fairly standard (although I don't fully understand the implications of the "Key Agreement" flag).
Developer Account PKCS12 Files
Next, once my developer account[0] was approved, I was sent two PKCS12 files (and the passwords used to decrypt them), corresponding to (I assume) two hosted MintChips.
[0]: actually, my friend's developer account - mine hasn't been approved yet.
Unpacking each of these PKCS12 files yields one private key and two certificates:
$ openssl pkcs12 -nodes -passin pass:hunter2 -info -in 1310000000008139.p12
MAC Iteration 1024
MAC verified OK
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1024
Bag Attributes
localKeyID: 82 8F 5D AD 42 DC C9 EA 25 2C 6E 65 C0 DB B8 20 52 7D 1D 15
friendlyName: 1310000000008139 Remote MintChip Client (Developer Challenge)
Key Attributes: <No Attributes>
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 1024
Certificate bag
Bag Attributes
localKeyID: 82 8F 5D AD 42 DC C9 EA 25 2C 6E 65 C0 DB B8 20 52 7D 1D 15
friendlyName: 1310000000008139 Remote MintChip Client (Developer Challenge)
subject=/CN=1310000000008139/OU=Remote MintChip Client/O=Royal Canadian Mint/C=CA
issuer=/CN=Remote MintChip Certificate Authority/OU=Remote MintChip/O=Royal Canadian Mint/C=CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Certificate bag
Bag Attributes
friendlyName: Remote MintChip CA (Developer Challenge)
subject=/CN=Remote MintChip Certificate Authority/OU=Remote MintChip/O=Royal Canadian Mint/C=CA
issuer=/CN=Remote MintChip Certificate Authority/OU=Remote MintChip/O=Royal Canadian Mint/C=CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
The Private Key
As far as I can tell there is nothing noteworthy about the private key.
The Client Authentication Certificate
Inspecting the first of the two certificates yields:
$ echo "$FIRST_CERT" | openssl x509 -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1198 (0x4ae)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
Validity
Not Before: Mar 6 10:06:45 2012 GMT
Not After : Mar 7 10:06:45 2013 GMT
Subject: CN=1310000000008139, OU=Remote MintChip Client, O=Royal Canadian Mint, C=CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:a7:1b:d9:81:17:ce:ae:b7:e8:46:6c:51:6b:b8:
...
62:20:0b:93:f7:02:4c:c5:dd
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature
X509v3 Extended Key Usage:
TLS Web Client Authentication
Signature Algorithm: sha1WithRSAEncryption
67:b9:d1:47:c2:62:82:60:1d:f9:01:04:de:c6:db:19:f3:3e:
...
17:16:60:0f
As can be seen by the "Extended Key Usage" extension, this certificate will be used for client-side certificate authentication.
I think this is pretty cool. When password protected, client-side certificates provide a nifty and unobtrusive form of two-factor authentication. I've only ever seen them used "in the wild" by CACert, so it's fun to see someone else using them.
As before, this certificate is signed by the "Remote MintChip Certificate Authority".
Nothing else is particularly surprising.
The Certificate Authority's Certificate
Now, on to the second certificate:
$ echo "$SECOND_CERT" | openssl x509 -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
Validity
Not Before: Mar 6 08:25:36 2012 GMT
Not After : Mar 7 08:25:36 2017 GMT
Subject: CN=Remote MintChip Certificate Authority, OU=Remote MintChip, O=Royal Canadian Mint, C=CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:ab:d9:7b:dc:a8:eb:55:59:05:46:23:ef:4d:76:
...
9a:c1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
X509v3 Key Usage:
Certificate Sign
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
Signature Algorithm: sha1WithRSAEncryption
41:95:6f:94:9a:3e:9d:03:af:a3:22:d6:0f:b6:7a:08:91:9d:
...
b3:da:88:bf
This is the certificate of the "Remote MintChip Certificate Authority" that has signed all the other certificates we've looked at.
Unlike all the other certificates we've looked at, though, this certificate is surprising: this certificate needs to be[0] added to the list of trusted CAs on all the devices which will use the MintChip hosted API... But it doesn't include any name constraints! [1] This means that, if the CA's private key was compromised, it could be used to forge certificates that would be trusted by any device which trusts this CA.
I find this omission a bit surprising; the hosted API's security appears to be well designed, which makes it seem unlikely that this was accidental.
Because the system is otherwise intelligent, I'm inclined to give MintChip the benefit of the doubt here, and assume that there is a good reason for omitting the name constraints. This is a developer-only preview of a proof-of-concept system, so it's possible they will be changing domains or using this CA in as-of-yet unexpected ways.
Edit: after some experimentaton, it seems that there is a less mysterious reason for the CA's lack of name constraints: they are ignored. For more details, see "Adventures in X.509: The Utterly Ignored nameConstraints".
tl;dr
The MintChip hosted API uses SSL client certificates for authentication, and both client and server certificates are signed by MintChip's own self-signed certificate authority.