-
Notifications
You must be signed in to change notification settings - Fork 449
ProofOfOwnership
There are a number of external systems which require a standardized proof of BOINC account ownership verification; this BOINC server extension provides this proof using existing public key cryptography within OpenSSL.
The user provides an external system's message, this is signed alongside their BOINC account ID using the BOINC project's private key then provided to the external system.
The external system verifies the signed message using the project's public key, establishing a simple offline proof of account ownership mechanism.
This is an optional extension which was implemented in v1.2.0 and can be easily implemented in an afternoon by a project administrator.
- Login to the project and go to the "Your Account" page
- Click on the "Account Ownership" link (the link says "Generate ownership proof").
- Note that this is only displayed if this proof of account ownership mechanism has been setup by the project administrator.
- Enter the message you wish to be signed (typically supplied by the external system that wants you to provide the proof of ownership).
- Submit the form.
- When successful the ownership proof will be shown on the website, copy and use the full contents to prove ownership of your account to an external system.
Everything you need to verify the signature is included within the XML snippet; the signature
tag is a base64 encoded SHA512 signature of the contents of msg
.
<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>
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
- Update the BOINC web server to at release 1.2.0 (or later).
- Alternatively cherry pick the changes introduced by PR#2965 into your homebrew BOINC server implementation.
- (optional) Configure reCAPTCHA in your
config.xml
so the form is protected. - Generate the account ownership public and private keys by running generate_account_ownership_keys.php via the command line in the BOINC web server html/ops directory.
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.
By implementing this BOINC server extension you improve the security of all external systems which require a proof of BOINC account ownership.
Ask the user to sign a secret message via the proof of account ownership mechanism on an individual BOINC project basis, they will return with XML snippets which include: master_url
, msg
, signature
Combine the master_url
with /get_project_config.php
to fetch XML which includes the project's ownership_signature_public_key
.
Verify the supplied signature
against the base64 encoded msg signed by the ownership_signature_public_key
.
Create your own process for the user supplying the generated XML snippet and how you perform verification, the following sections are examples for inspiration.
Follow the 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>
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.")
Create the following bash script with filename 'verify.sh'.
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