wiki:ProofOfOwnership

Version 6 (modified by Kevin Reed, 5 years ago) (diff)

--

Proof of Account Ownership

There are a number of external systems that need to verify that a particular person is in control of a user account. The Proof of Account Ownership mechanism enables this proof using public key cryptography (SHA512 signature). This is done by having the user entering a message provided by the external system which is then signed alongside their account ID using the project's private key. The external system is then able to verify the signed message using the projects public key and thus provides proof that the user does in fact control the account.

This is an optional extension to the BOINC generic project website. Is is available since server version "TODO".

User guide

Instructions

  1. Login to the project and go to the "Your Account" page
  2. Click on the "Account Ownership" link (the link says "Generate ownership proof"). Note that this is only displayed if the proof of account ownership keys have been created.
  3. Enter the message you wish to be signed (typically supplied by the external system that wants you to provide the proof of ownership).
  4. Submit the form.
  5. When successful the ownership proof will be shown on the website, copy and use the full contents to proof ownership of your account.

Example XML output

<account_ownership_verification>
<master_url>http://domain.tld/project_name/</master_url>
<msg>1 Enter text</msg>
<signature>BASE64_SIGNED_MSG</signature>
</account_ownership_verification>

Project administrator guide

Changes to web server

See modifications introduced by PR#2965 if you want to cherry-pick the commits.

html/inc/account_ownership.inc - new file
html/inc/util.inc - fixing ttok warnings
html/inc/user.inc - add link to account ownership form within the profile

html/user/get_project_config.php - include the account ownership public key
html/user/account_ownership.php - new file: UI that allows a user to have a message provided by an external system signed and linked to their account

html/ops/index.php - Add link to check_account_ownership_keys.php 
html/ops/check_account_ownership_keys.php - new file: provides a UI for a project admin to check if the account ownership keys are setup and installed
html/ops/generate_account_ownership_keys.php - new file: command line script to create the account ownership keys

Changes required to integrate this functionality:

  1. Install the latest BOINC PR#2965 web server changes
  2. (optional) Configure reCAPTCHA in your config.xml so the form is protected.
  3. Generate the account ownership public and private keys by running generate_account_ownership_keys.php using the commandline in the BOINC web server html/ops directory.

Security

The private key needs to remain on the web server so that it can be used to sign message. If this private key is compromised, then proof of account ownership signatures can be forged. It's important to maintain an updated and secure BOINC project webserver to reduce the risk of this happening.

If you believe that the private key has been compromised, you can generate a new key pair using the generate_account_ownership_keys.php in the BOINC web server html/ops directory. Existing signed messages will no longer be valid and users will need to regenerate their signed messages to maintain a current proof of account ownership on external systems. You should inform users if you need to take this action so that they understand what is happening.

External systems guide

Verifying signed messages

The content of the signature tag is a base64 encoded SHA512 signature of the content of the msg tag. See Example XML output section above. Basically everything you need to verify the signature is in the XML snippet. You can use the <master_url> to get the public key, which is published in the XML output from get_project_config.php.

The following scripts and procedures are just examples. You should create your own process on how the user needs to supply the generated XML snippet to you and how you do the verification. Also keep in mind that the structure of the snippet might be modified in the future and might differ slightly between projects.

Pre-requisites

Follow the above user guide with a project that has this feature enabled, copy the output XML text snippet and save to 'xml_data.xml'.

Extract the PUBLIC_KEY_VALUE from the XML output produced by '<master_url>/get_project_config.php' into a file called 'ownership_sign_public.pem'. Don't include the 'ownership_signature_public_key' tags in the file, don't include trailing return/newline characters in the text file.

<ownership_signature_public_key>PUBLIC_KEY_VALUE</ownership_signature_public_key>

Python verification script

The below script takes the public key and the saved xml file and prints whether it's valid or not. Requires the following python modules: pycryptodome, base64, xmltodict

from Crypto.PublicKey import RSA # package: pycryptodome
from Crypto.Signature import PKCS1_v1_5 
from Crypto.Hash import SHA512
from base64 import b64decode
import xmltodict # For handling XML data

with open('xml_data.xml') as fd: # Entire output XML snippet
    boinc_xml_data = xmltodict.parse(fd.read())

with open('ownership_sign_public.pem') as f: # public key *.pem file
    public_key_data = f.read()

message = boinc_xml_data['account_ownership_verification']['msg']
signature = boinc_xml_data['account_ownership_verification']['signature']

rsakey = RSA.importKey(public_key_data) 
verifier = PKCS1_v1_5.new(rsakey)
digest = SHA512.new()
digest.update(bytes(message, encoding = "utf8"))

if verifier.verify(digest, b64decode(signature)):
    print("Successfully verified Account Ownership.")
else:
    print("Failed to verify UserID ownership.")

Linux command line

Create the following bash script with filename 'verify.sh'.

#!/bin/bash
SIG=$(sed -n 's/<signature>\(.*\)<\/signature>/\1/p' xml_data.xml)
MSG=$(sed -n 's/<msg>\(.*\)<\/msg>/\1/p' xml_data.xml)
echo -n $SIG > signature.txt
echo -n $MSG > msg.txt
base64 -d signature.txt > decoded_signature.txt
openssl dgst -sha512 -verify ownership_sign_public.pem -signature decoded_signature.txt msg.txt

Enable it to be executable then run the script

chmod +x verify.sh
./verify.sh

Expected successful output:

Verified OK