vCARDs on iOS without hosting them

You want to
a) share your contact details via NFC,
b) but support iPhones aswell, and
c) don’t want to host your private data somewhere?
I have the solution for you!

You can share your vCARD as link, without ever uploading it anywhere!

My idea is essentially is a mix of storing the vCARD locally, but using a website link to serve it to iPhone users.
It reads all the vCARD data from the location.hash in the url, your vCARD is never on the server, but encoded in the URL.
The website just serves a script to convert this URL back to a vCARD and save it.
This is possible becasue location.hash (everything after # in a url) is never sent to the server, so you can easily store this sensitive data there without leaking it to the server.

You can try it here: https://vcard-test.tiiny.site/#QkVHSU46VkNBUkQKRk46T3NjYXIgZGVsIFBvem8KTjpkZWwgUG96byBUcmlzY29uO09zY2FyClNPUlQtU1RSSU5HOlBvem8KRU5EOlZDQVJECg==

Although I don’t make any promises and it looks shitty af, you could in theory already use this.
(The service will stop working in 7 days, as it’s hosted for free.)

To make your own, you need to base64 encode your vCARD and replace everything after # in the url above with the result.

On linux you can generate such urls like this: echo "https://vcard-test.tiiny.site/#`base64 < mycontact.vcf`"

This is a very very dumbed down proof of concept of this project. Big vCARDs make for long URLs, which wont fit on the chip, so this doesn’t even solve that use case completely.

You can just inspect the source code on the website, there is no backend, tiiny.site just serves my html.


I dont want to let this idea die, but I also don’t want to do all the work the real project, a secure contact sharing platform, requires, so this is all I can give you now. I think this location.hash thing is by far the best approach to sharing things with implants.

7 Likes

Generating your own URL on android.

  1. Install Termux (to have a linux shell on your phone)
  2. Go to your contacts, select your contact, and share it to Termux (Share > File > Termux > open folder)
  3. Run echo "https://vcard-test.tiiny.site/#`base64 < mycontact.vcf`" replacing mycontact.vcf with the name of the file.

You should see your link now. Hint: when copying it from Termux, make sure to remove all the " " spaces it added where the newlines were or the link will not work, sorry, no better solution until now




2 Likes

So… since that site’s down I put it on this server but I don’t expect it to stay there. So this time I’ll also save the source here, so you can host this html.
https://disbe.me/static/vcard.html#QkVHSU46VkNBUkQKRk46T3NjYXIgZGVsIFBvem8KTjpkZWwgUG96byBUcmlzY29uO09zY2FyClNPUlQtU1RSSU5HOlBvem8KRU5EOlZDQVJECg==

Source
<title>vCARD Test</title>
<center>
<script>
//Taken from https://stackoverflow.com/questions/35038884/download-file-from-bytes-in-javascript#37340749
function base64ToArrayBuffer(base64) {
  var binaryString = window.atob(base64);
  var binaryLen = binaryString.length;
  var bytes = new Uint8Array(binaryLen)
  for (var i = 0; i < binaryLen; i++) {
    var ascii = binaryString.charCodeAt(i)
    bytes[i] = ascii
  }
  return bytes
}
if (location.hash.length > 10) {//just to check if there's a contact
  var bytes = base64ToArrayBuffer(location.hash.substr(1))
  location.hash = "" // hide base64 data
  var blob = new Blob([bytes], { type: "text/vcard" })
  var link = document.createElement("a")
  link.href = window.URL.createObjectURL(blob)
  console.log(link.href)
  link.download = "name.vcard"
  //TODO validate vCARD before downloading
  link.click()
  document.write("contact should be downloaded")
} else {
  document.write("Share your vCARD as url without hosting it somewhere!<br>To share a vcard base64 encode the content and append it to this url with a #")
}
</script>
</center>
1 Like

I was thinking the same thing and googled around and found your thread here,
Have you ever thought about using uri schemes for achieving the same goal but offline?

I just created my profile here to reply on this topoc, couldn’t really message you. Would be great if you can message me here

1 Like

Yeah I tried data:text/vcard, uris and similar things, that doesn’t work. Idk about more pseudo protocols suitable for this.

@anon3825968 also did lots of research into this and his solution is to not support iPhones.

I’m convinced using location.hash is the only way. Offline just isn’t possible.

But this trick doesn’t require a “real server”. Cheap wordwide static hosting would work. Amazon has servers in like every city, I do not have this offline requirement.

I have no problem hosting stuff, but my goal is to make it work offline

If you have an iPhone just try inputting smt like contact:// in safari, it pops a dialog where you can open contacts app, basically figuring out how this works will help with offline support :grimacing:
I was looking around all uri URI schemes available ( Uniform Resource Identifier (URI) Schemes )
Basically there is no contact there but you can try and see it working!!!
I also looked into getting something like blob to work, no yet luck, would be great if you find something in this way and we can collaborate on finally making something work offline

1 Like

I do not have an iPhone which makes all this extra hard.
I relied on a friend and I really do not want to send him another 50 links to write to his nfc sticker haha.

Also contact isn’t available on android.

I’m sure it isn’t allowed from NDEF at iPhones either.

If you find any protocol that e.g. allows rendering a SVG or anything that allows javascript, for android and iPhones, I’m interested, but I believe it’s not possible (or wanted) on iPhones.

I’m not wasting more time on this offline requirement, if I spend time on contacts I put it into the encrypted online card I’m making.

Support for the text/vcard mimetype is nonstandard and is an Android thing (which, I suppose makes it a de-facto standard though). Apple doesn’t support it probably out of spite, because supporting it would be completely trivial.

AFAIK. iOS users can only work with URI NDEF records to share their data.

Thanks for posting this @yeka as I just stumbled over this trying to do the same thing.
The issue with iOS is it only supports a limited number of URI schemes in their NFC Background Scanning.

So either you have a tel: or email: … as both of them work but are really quite useless. Otherwise the above code hosted somewhere is the only solution. Which is great as thankfully you posted the source code and it worked a treat for me.

2 Likes

You inspired me to make this a service, DT hosts it now (so it’ll probably stay).
Also, I still get pings from this thread every now and then so all you please see:

2 Likes