{"id":31042147,"url":"https://github.com/skrysm/hdvp","last_synced_at":"2026-04-16T00:32:36.173Z","repository":{"id":56055339,"uuid":"282259070","full_name":"skrysm/hdvp","owner":"skrysm","description":"The Human Data Verification Protocol","archived":false,"fork":false,"pushed_at":"2025-09-13T15:23:34.000Z","size":172,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-27T12:37:44.210Z","etag":null,"topics":["dotnet","integrity-checker","protocol","security"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skrysm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-07-24T15:47:27.000Z","updated_at":"2025-09-13T15:23:38.000Z","dependencies_parsed_at":"2025-09-14T11:31:14.622Z","dependency_job_id":"26b36587-6233-410e-b440-a3b3ca94e55f","html_url":"https://github.com/skrysm/hdvp","commit_stats":null,"previous_names":["skrysm/hdvp","skrysmanski/hdvp"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/skrysm/hdvp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skrysm%2Fhdvp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skrysm%2Fhdvp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skrysm%2Fhdvp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skrysm%2Fhdvp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skrysm","download_url":"https://codeload.github.com/skrysm/hdvp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skrysm%2Fhdvp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31866339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"ssl_error","status_checked_at":"2026-04-15T15:24:39.138Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotnet","integrity-checker","protocol","security"],"created_at":"2025-09-14T11:03:55.874Z","updated_at":"2026-04-16T00:32:36.113Z","avatar_url":"https://github.com/skrysm.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Human Data Verification Protocol (HDVP)\n\n[![NuGet](https://img.shields.io/nuget/v/HDVP.svg)](https://www.nuget.org/packages/HDVP/)\n\nThe *Human Data Verification Protocol* provides a way to securely transmit arbitrary data over an insecure network.\n\n\"Securely\" in this case means that the data is not modified in transit (integrity). However, the data is *not* encrypted (confidentiality).\n\nTo verify that the data was not modified by a man-in-the-middle attacker, a human user must enter a short code on the receiver side. This code (called an **HDVP verification code**) is basically a hash of transmitted data - but with some modifications to make it easier to use (see design notes).\n\n## Use Case\n\nThe primary use case for this protocol is to transfer the public key of a self-signed (HTTPS) certificate (or root CA) onto a freshly installed machine (computer). This certificate would then be used to secure any other traffic afterwards.\n\nIn this scenario, the traffic for downloading the certificate can't be encrypted (e.g. regular HTTP rather than HTTPS). However, we would like to have (a certain degree of) confidence that the downloaded certificate hasn't been modified by a man-in-the-middle attacker. This is what HDVP does.\n\nYou *could* upload the certificate to a server (that runs HTTPS with a CA signed certificate) and then download it on the new machine - but this requires an Internet connection (may or may not be a problem) and setting up a server and uploading a file securely (in an *automatic* way) is a lot of work. HDVP tries to solve this problem in a simple (yet still secure) way.\n\nAlso, HDVP is designed primarily for home or small business networks. Large companies have other (better = more effort) ways to deal with this problem (like pre-provisioned server images or physically secured networks).\n\n## The Basic Flow\n\nThe basic flow of HDVP is as follows:\n\n1. You provide HDVP with the binary data to transmit.\n1. HDVP provides you with a 32 byte salt and a (human-readable) verification code.\n1. You download the binary data and the salt to the target machine.\n1. On the target machine, you provide HDVP with the downloaded data, salt and enter the verification code.\n1. HDVP tells you whether the verification code matches the downloaded data.\n\nNote: HDVP itself does *not* provide any means to transmit the binary data or the salt to the target machine. HDVP just provides the verification protocol.\n\nTo increase security, the verification code is only valid for a certain time (by default, 1 minute).\n\n## The Verification Code\n\nThe verification code is human-readable and human-typeable.\n\nIts length is configurable (9 - 40 characters).\n\nA verification looks like this:\n\n    dry9odphhaa3\n\n## Using the C# Implementation\n\nThe directory `src` in this repository contains the HDVP reference implementation (in C#).\n\nOn the server side (that provides binary data to download), you first need to create an instance of `HdvpVerificationCodeProvider`:\n\n```c#\nbyte[] myDataAsByteArray = ...\nvar codeProvider = new HdvpVerificationCodeProvider(myDataAsByteArray);\n```\n\nOr:\n\n```c#\nStream myDataAsStream = ...\nvar myVerifiableData = HdvpVerifiableData.ReadFromStream(myDataAsStream);\nvar codeProvider = new HdvpVerificationCodeProvider(myVerifiableData);\n```\n\nTo get the currently valid verification code (remember that validation codes are only valid for a certain amount of time), use the `GetVerificationCode()` method:\n\n```c#\nHdvpVerificationCode currentVerificationCode = codeProvider.GetVerificationCode();\n```\n\nYou can check for how long the current verification code is valid via `codeProvider.VerificationCodeValidUntilUtc`.\n\nThe `HdvpVerificationCode` class provides you with two important properties:\n\n* `Code`: the verification code as a string\n* `Salt`: the salt of the verification code\n\nYou can now display the `Code` to the user and provide the `Salt` as download for the client.\n\nOn the client side, you then:\n\n1. download the binary data from the server\n1. download the salt from the server\n1. let the user enter the verification code\n\nWith the entered code, you first want to checked whether its format is correct:\n\n```c#\nvar verificationCodeCheckResult = HdvpVerificationCode.CheckFormat(verificationCodeAsString);\nif (verificationCodeCheckResult != HdvpFormatValidationResults.Valid)\n{\n    // Error reporting here\n}\n```\n\nThe last step is to verify the binary data against the verification code the user entered:\n\n```c#\nbyte[] binaryData = ...;\nbyte[] salt = ...;\nvar hdvpVerificationCode = HdvpVerificationCode.Create(verificationCodeAsString, salt);\nif (!hdvpVerificationCode.IsMatch(binaryData))\n{\n    // Error handling here\n}\n```\n\n*Notes:*\n\n* It's recommended to download the salt *before* asking the user to enter the verification. This is because the salt is changed every time the verification code changes and by downloading it before asking the user to enter the verification, it doesn't matter if the user is too slow to enter the code.\n* It's also recommended (for the same reason) to re-download the code *every time* before asking the user to enter the verification code.\n\n## Other Documentation\n\nThe specification of HDVP can be found in [SPEC.md](SPEC.md).\n\nBackground information on the design of HDVP can be found in [DESIGN-NOTES.md](DESIGN-NOTES.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskrysm%2Fhdvp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskrysm%2Fhdvp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskrysm%2Fhdvp/lists"}